我正在實現使用Sinch進行視頻聊天,但是我找不到在呼叫開始後禁用傳出視頻的方法。如何在Sinch中禁用視頻
這是記錄在某處嗎?
如果它不被SDK支持,是否有辦法(甚至是黑客)「截取」視頻流並阻止它被髮送。
我正在實現使用Sinch進行視頻聊天,但是我找不到在呼叫開始後禁用傳出視頻的方法。如何在Sinch中禁用視頻
這是記錄在某處嗎?
如果它不被SDK支持,是否有辦法(甚至是黑客)「截取」視頻流並阻止它被髮送。
顯然,在SDK中沒有官方的方法來做到這一點,但這裏有一個按預期工作的黑客。長話短說,用一些運行時「魔法」,我們可以攔截由Sinch發起並控制它的AVCaptureSessoin
。
方法如下:
extension AVCaptureSession {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
// make sure this isn't a subclass
if self !== AVCaptureSession.self {
return
}
dispatch_once(&Static.token) {
let originalSelector = #selector(AVCaptureSession.init)
let swizzledSelector = #selector(AVCaptureSession.hd_init)
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
}
@nonobjc static var hd_currentSession: AVCaptureSession? = nil
func hd_init() {
hd_init() // at runtime this is the original `init` implementation
AVCaptureSession.hd_currentSession = self
}
}
一個簡要解釋:第一部分是兩種方法只是基本的運行混寫,沒有什麼具體到這個實現。
也就是說,我們有我們自己的AVCaptureSession.hd_init
更換的AVCaptureSession.init
實施(hd
只是任何前綴,以避免方法名潛在爭食)。
注意
在
hd_init
我們調用hd_init
。這有點令人費解,但它是如何運作的:當我們執行那段代碼hd_init
已被原始init
所取代時,所以我們實際上正在調用原始實現,這正是我們想要的。
我們的init
自定義實現具有存儲靜態參考實例,我們將稱之爲hd_currentSession
的只是目的。
我們完成了!
現在從應用程序的任何地方我們都可以獲得對當前AVCaptureSession
的引用並停止它/隨意啓動它。
例如
func toggleVideo() {
if let session = AVCapture.hd_currentSession {
if session.running {
session.stopRunning()
} else {
session.startRunning()
}
}
}
在Sinch視頻直播已開始後的任何時間,我們可以簡單地調用toggleVideo()
CAVEAT
停止捕獲會話會導致視頻以「凍結」到最後一幀。我沒有在iOS端解決這個問題,但我注意到,在Javascript API上,您在視頻
MediaTrack
上獲得了"muted"
事件。鑑於此,您可以 - 例如 - 使用onmuted
事件將視頻隱藏在其他客戶端。