Sinch Video 通话声音来自前置扬声器

Posted

技术标签:

【中文标题】Sinch Video 通话声音来自前置扬声器【英文标题】:Sinch Video calling sound is coming from front speaker 【发布时间】:2017-12-26 11:32:49 【问题描述】:

我已经在 ios swift 项目中实现了 sinch 视频通话,我遵循了 sinch 实现文档https://www.sinch.com/docs/video/ios/#calling 中给出的所有流程。而且我能够成功实施,但我的视频声音来自前置扬声器。我怎么解决这个问题??在我的代码下面:

var client: SINClient?
var sinCall : SINCall?

配置 sinch

//MARK: Configuring Sinch Delegate
func configuringSinch()
    //Configuring Client Key
    client = Sinch.client(withApplicationKey: Constants.SINCH_APP_KEY, applicationSecret: Constants.SINCH_PRIVATE_KEY, environmentHost: Constants.SANDBOX_ENVIRONMENT, userId: Utility().getUserId())

    client?.call().delegate = self
    client?.setSupportCalling(true)
    client?.enableManagedPushNotifications()
    client?.start()
    client?.startListeningOnActiveConnection()

    let vcCont = client?.videoController()
    self.vwLocalView.addSubview((vcCont?.localView())!)

    self.sinCall?.delegate = self



//MARK: Sinch Video Call Delegate
func clientDidStart(_ client: SINClient!) 
    print("Client Did Start")


func clientDidFail(_ client: SINClient!, error: Error!) 
    print("Client failed : \(error)")
    player?.stop()

func clientDidStop(_ client: SINClient!) 
    print("Client Did Stop")
    player?.stop()


    //MARK: Video Call Did Recieve
func client(_ client: SINCallClient!, didReceiveIncomingCall call: SINCall!) 
    print("Did Recieve Incoming Call")

    playRingtoneSound() // Playing Audio
    call.delegate = self;
    self.sinCall = call


 //MARK: Call Did Add Video Track
func callDidAddVideoTrack(_ call: SINCall!) 
    let videoCont = client?.videoController()
    vwRemoteView.addSubview((videoCont?.remoteView())!)


func callDidEnd(_ call: SINCall!) 
    sinCall?.hangup()


【问题讨论】:

【参考方案1】:

这是您可以管理 SINAudioController 来管理音频输出的方法。

func audioController() -> SINAudioController 
        return (client?.audioController())!
    

//MARK: Video Call Did Recieve
func client(_ client: SINCallClient!, didReceiveIncomingCall call: SINCall!) 
    audioController().enableSpeaker()

    playRingtoneSound() // Playing Audio
    call.delegate = self;
    self.sinCall = call


// In SINCallDelegate
func callDidEstablish(_ call: SINCall!) 

    //to disableSpeaker
    audioController().disableSpeaker()

试试这个手动管理 AudioOutput Session

// MARK: AudioOutput Session

// to enable front speaker manually
func setSessionPlayerOn()

    do 
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
     catch _ 
    
    do 
        try AVAudioSession.sharedInstance().setActive(true)
     catch _ 
    
    do 
        try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.none)
     catch _ 
    


// to enable speaker manually
func setSessionPlayerSpeaker()

    do 
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
     catch _ 
    
    do 
        try AVAudioSession.sharedInstance().setActive(true)
     catch _ 
    
    do 
        try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
     catch _ 
    


// to turnoff AudioOutput Session manually
func setSessionPlayerOff()

    do 
        try AVAudioSession.sharedInstance().setActive(false)
     catch _ 
    

【讨论】:

这与我在进行视频通话时收到的声音无关。 好的,但是当您编写来自前置扬声器的视频声音时,它将从扬声器输出。您可以在控制器 audioController().enableSpeaker() 中的任何位置使用它。让我知道它是否有帮助 我已将答案编辑为 audioController().enableSpeake 不适合您。您可以手动管理 AudioOutput Session 来实现这一点。 你的问题还存在吗? 修复了@Govind 的问题【参考方案2】:

使用此功能

 func callDidEstablish(_ call: SINCall!) 

    let audio = APPDELEGATE.client?.audioController()
    audio?.disableSpeaker()

   // self.startCallDurationTimerWithSelector()
    appDelegate.client?.audioController().stopPlayingSoundFile()


这对我有用。

【讨论】:

【参考方案3】:
class MainVC: UIViewController,SINCallDelegate 
   // var client: SINClient?

    private let videoController = SinchManager.sharedInstance.client!.videoController()
    private let audioController = SinchManager.sharedInstance.client!.audioController()


    private let callClient: SINCallClient
    private var call: SINCall!

    let username: String

    @IBOutlet weak var otherView: UIView!

   // private var mainView: SinchView  return view as! SinchView 

    @IBAction func call_btn(_ sender: UIButton) 
        answer()
    
    @IBAction func end_btn(_ sender: UIButton) 
        decline()
    


    override func loadView() 
       // view = SinchView()
        view = otherView
    

    init(username: String) 
        self.username = username
        self.callClient = SinchManager.sharedInstance.client!.call()

        super.init(nibName: nil, bundle: nil)
    

    required init?(coder aDecoder: NSCoder) 
        print("init(coder:) has not been implemented " + String(describing: aDecoder))

        fatalError("init(coder:) has not been implemented " + String(describing: aDecoder))
    

    override func viewDidLoad() 
        super.viewDidLoad()


        call.delegate = self

        //self.mainView.videoView.addSubview(self.videoController.localView())
        otherView.addSubview((self.videoController?.localView())!)

        self.videoController?.localView().contentMode = .scaleToFill

        if self.call.direction == SINCallDirection.incoming 
            self.audioController?.startPlayingSoundFile(self.pathForSound(string: "incoming.wav") as String, loop: true)
        

        if self.call.details.isVideoOffered 
            print("video offered")
            //self.mainView.videoView.addSubview(self.videoController.localView())
            otherView.addSubview((self.videoController?.localView())!)

            self.videoController?.localView().contentMode = .scaleToFill
        

        otherView.addSubview((self.videoController?.localView())!)
       // mainView.answerButton.addTarget(self, action: #selector(answer), forControlEvents: .TouchUpInside)
       // mainView.declineButton.addTarget(self, action: #selector(decline), forControlEvents: .TouchUpInside)
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        self.audioController?.enableSpeaker()
    

    func pathForSound(string: String) -> NSString 
        let nsSt = Bundle.main.resourcePath! as NSString

        return nsSt.appendingPathComponent(string) as NSString
    

    func answer() 
        call.answer()
    

    func decline() 
        call.hangup()
    

    func callDidEstablish(call: SINCall!) 
        print("callDidEstablish")
        let audio = SinchManager.sharedInstance.client!.audioController()
        audio?.disableSpeaker()

        // self.startCallDurationTimerWithSelector()
       SinchManager.sharedInstance.client!.audioController().stopPlayingSoundFile()
    

    func callDidEnd(call: SINCall!) 
        print("callDidEnd")
    

    func callDidProgress(call: SINCall!) 
        print("callDidProgress")
        self.audioController?.startPlayingSoundFile(self.pathForSound(string: "ringback.wav") as String, loop: true)
    

    func callDidAddVideoTrack(call: SINCall!) 
        print("callDidAddVideoTrack")
        otherView.addSubview((self.videoController?.localView())!)
    

【讨论】:

以上是关于Sinch Video 通话声音来自前置扬声器的主要内容,如果未能解决你的问题,请参考以下文章

如何在通话期间以编程方式在 iPhone 的两个扬声器上播放声音

来自麦克风的声音与来自扬声器的声音

如何监控设备的音频输出以判断声音是不是来自扬声器/耳机插孔?

来自耳机的 OpenVidu Publisher 声音

从 iOS 应用程序到蓝牙扬声器播放现场声音

OpenAL 输出声音 5.1