Comments (17)
Just so we narrow down the issue more, can you initialize the background publisher with audioTrack = false and check if you get the same error. If it works it can be an audio driver acquisition issue (maybe some other app is playing audio or CallKit itself is playing a ringtone/audio etc..).
Thanks
from opentok-ios-sdk-samples-swift.
@IGitGotIt audioTrack = false seems to work. The session publishes, the same AURemoteIO.cpp
lines print to the console. And, assuming you know this, but there doesn't seem to be any published sound even the OTPublisher.publishAudio
is set to true after creation.
from opentok-ios-sdk-samples-swift.
Actually, I'm not able to publish audio at all... even when the app is active. The session connects; all parties can publish and receive video, but no audio is received from iOS devices. With the DefaultAudioDevice
from the custom audio driver sample, we sometimes get a few moments of audio before it cuts out. Without setting a custom audio device, ...nothing.
I think this is separate from the timeout issue, though.
Also, the OTPublisher.init() is now hanging the main thread. Should that be created in the background?
Edit: The audio cuts out after CXProviderDelegate.provider(_:didActivate:AVAudioSession)
is called by CallKit. I'm guessing the provided AVAudioSession is not the one set up by OTAudioDeviceManager.. ? ...this is needed even when the app is active so that the system knows a "call" is in progress and gracefully handles another phone call coming in.
the AVAudioSession
passed to the CXProviderDelegate
method is the same as returned by AVAudioSession.sharedInstance()
from opentok-ios-sdk-samples-swift.
I recommended turning off audioTrack so we can narrow the issue and diagnose the problem. It was not a solution and yes, audio will not work . With the publisher now publishing, we can assume it was an audio driver acquisition problem originally.
My guess, w/o looking at your code , is that you need to activate the audio rendering and capturing whenever your logic/flow dictates. Till then the audio drivers will be in a passive mode. We have an ObjC sample app , which serializes audio driver acquisition, while a ringtone plays first. Maybe you need to implement something similar to it .
from opentok-ios-sdk-samples-swift.
Oh, to clarify, the audio would cease with audioTrack=true. CallKit seemed to be doing something. A route change coincides with the didActivate call.
from opentok-ios-sdk-samples-swift.
Both our use cases are currently broken. These are the steps we perform for each
PushKit Initiated
- Receive Notification
- Call
OTAudioDeviceManager.setAudioDevice(audioController!)
setting to an instance ofDefaultAudioDevice
from this repo - Call CXProvider.reportNewIncomingCall()
- User Accepts Call, reported by
CXProviderDelegate.provider(_, perform: CXAnswerCallAction)
- Call
DefaultAudioDevice.startCapture()
- Create publisher:
OTPublisher(delegate:settings:)
,videoTrack=true
andaudioTrack=true
- Set
OTPublisher.publishVideo=false
,OTPublisher.publishAudio=true
- Create session:
OTSession(apiKey:sessionId:delegate)
- Call
OTSession.connect()
- Wait for
sessionDidConnect()
callback, then - Call
OTSession.publish()
- Receive
session(_:streamCreated:OTStream)
as usual - Eventually receive
publisher(_:didFailWithError:OTError)
with the timeout - Call
action.fail()
on the CXAnswerCallAction from step 4 because of the timeout (would callaction.fulfill()
on successful publish).
User Initiated
- Create publisher:
OTPublisher(delegate:settings:)
,videoTrack=true
andaudioTrack=true
(we offer a selfie preview to the user before they join a session) - Set
OTPublisher.publishVideo=true
,OTPublisher.publishAudio=true
- Call
OTAudioDeviceManager.setAudioDevice(audioController!)
setting to an instance ofDefaultAudioDevice
from this repo - Create session:
OTSession(apiKey:sessionId:delegate)
- Call
OTSession.connect()
- Wait for
sessionDidConnect()
callback, then - Call
OTSession.publish()
- Receive
session(_:streamCreated:OTStream)
, hold on subscribing until publish succeeds - Eventually receive
publisher(_:didFailWithError:OTError)
with the timeout
At other times, the publishing would succeed for the User Initiated flow, but only a few moments of audio would publish before the outgoing stream went silent. In that case, we would do the following:
- Wait for publish success:
publisher(_:streamCreated:OTStream)
- Call
DefaultAudioDevice.startCapture()
- Create
CXStartCallAction
transaction for CXCallController. The system knows we're in a call now. - Subscribe to all held streams
- Log a few called to
DefaultAudioDevice.recordCb
- Log a last call to
DefaultAudioDevice.onRouteChangeEvent
before calls torecordCb
stopped.
from opentok-ios-sdk-samples-swift.
Seeing this error now:
ERROR[OpenTok]:Audio device error: startCapture.AudioOutputUnitStart returned error: what
By removing any use of the DefaultAudioDevice and the CXCallController, I was able to make the User Initiated flow above work on a second device, but not my primary phone. Reintroducing the DefaultAudioDevice still allowed the second device to work, but the primary device still timed out publishing. Adding back the calls for CXCallController, the secondary device would publish audio for a few moments and then go silent after the CXCallController did its thing and fired its didActivate:AVAudioSession
callback in response to the CXStartCallAction
described above. The primary device again had no change.
DefaultAudioDevice fails at startCapture()
. It gets an error result from AudioOutputUnitStart
, which doesn't always coincide with the error message listed at the top of this post. That message is absent.
from opentok-ios-sdk-samples-swift.
Error in DefaultAudioDevice.setupAudioSession() during PushKit flow:
Error setting up audio session Error Domain=NSOSStatusErrorDomain Code=561017449 "Session activation failed" UserInfo={NSLocalizedDescription=Session activation failed}
It fails at the try session.setActive(true)
call.
from opentok-ios-sdk-samples-swift.
Found a possible solution/work-around the User Initiated Flow. The startCapture()
method of DefaultAudioDevice
is called automatically by the OpenTok SDK. I'm not sure where. The backtrace just had it on the WebRTCThread, so that I'm not sure what queued it. In any case, by making this a no-op, I was able to call it manually in the CXProviderDelegate.provider(_:didActivate:AVAudioSession)
callback. This, btw, was how my DefaultAudioDevice was already set up, only it was calling startCapture()
, which I guess had already been called earlier. So I'm guessing the latest update changed that behavior.
Still having an issue with the PushKit Initiated flow.
from opentok-ios-sdk-samples-swift.
Found some better behavior with the PushKit flow by moving the action.fulfill()
earlier in the flow when the sessionDidConnect()
callback. Fulfilling the action lets CallKit proceed to calling CXProviderDelegate.provider(_:didActivate:AVAudioSession)
, and that's when the audio can be set up, session.publish(), and any outstanding streams can be subscribed to.
With this, the printed errors are reduced to:
2022-11-09 17:48:57.609935-0500 WorkBeta[18066:2488628] [as] ATAudioSessionPropertyManager.mm:89 Error 2003329396 while getting property value from AVAudioSession
CoreAudio repeatedly triggers recordCb
and renderCb
for 15 seconds, and then the publishing timeout error still occurs.
from opentok-ios-sdk-samples-swift.
The next question, which I can't answer, is why would the publisher time out even if recordCb
is writing data to the OTAudioBus?
from opentok-ios-sdk-samples-swift.
Working Flows for anyone who might come across this in the future.
One change to DefaultAudioDevice: remove AVAudioSession.sharedInstance().setActive(true)
from setupAudioSession()
. This is handled by CallKit. I reverted the change discussed above that moved the startCapture()
functionality to a different function. By holding all publish and subscribe calls, we can, in turn, hold off on the SDK from calling startCapture()
. The custom audio driver is also necessary to be able to call to setupAudioSession()
earlier than session.publish()
would, specifically in the CXProviderDelegate callback.
User Initiated Flow (Outgoing call)
- Call
OTAudioDeviceManager.setAudioDevice(audioController!)
setting to an instance ofDefaultAudioDevice
- Create publisher:
OTPublisher(delegate:settings:)
,videoTrack=true
andaudioTrack=true
- Set
OTPublisher.publishVideo=true
,OTPublisher.publishAudio=true
- Create session:
OTSession(apiKey:sessionId:delegate)
- Call
OTSession.connect()
- Wait for sessionDidConnect() callback, then
- Receive session(_:streamCreated:OTStream), hold on subscribing until publish succeeds
- Call
DefaultAudioDevice.setupAudioSession()
- Create and send CXStartCallAction transaction for CXCallController.
- Wait for
CXProviderDelegate.provider(_:didActivate:AVAudioSession)
, then - Finally Call
OTSession.publish()
- Wait for publish success:
publisher(_:streamCreated:OTStream)
, then - Subscribe to all held streams
PushKit Flow (Incoming Call)
- Receive Notification
- Call
OTAudioDeviceManager.setAudioDevice(audioController!)
setting to an instance ofDefaultAudioDevice
- Call
CXProvider.reportNewIncomingCall()
- User Accepts Call, reported by
CXProviderDelegate.provider(_, perform: CXAnswerCallAction)
- Call
DefaultAudioDevice.setupAudioSession()
- Create publisher:
OTPublisher(delegate:settings:)
- Set
OTPublisher.publishVideo=false
,OTPublisher.publishAudio=true
- Create session:
OTSession(apiKey:sessionId:delegate)
- Call
OTSession.connect()
- Wait for
sessionDidConnect()
callback, then - Receive
session(_:streamCreated:OTStream)
as usual, queue streams for later subscription - Call
action.fulfill()
on earlierCXAnswerCallAction
- Wait for
CXProviderDelegate.provider(_:didActivate:AVAudioSession)
, then - Call
OTSession.publish()
- Wait for publish success:
publisher(_:streamCreated:OTStream)
, then - Subscribe to all held streams
The downside of this is that the system's calling UI (used when you don't unlock the phone) moves from a "connecting" state to a "in progress" state with the upwardly counting timer as soon as action.fulfill()
is called, but no streams are published or subscribed at that moment. So there's a few moments silence when the user expects to be able to start talking.
Leaving this open so that the dev's still address the timeout I was getting before.
from opentok-ios-sdk-samples-swift.
Any ideas, @IGitGotIt?
from opentok-ios-sdk-samples-swift.
I got this issue also. I am using tokbox version 2.18.1. Any ideas about this. Please
from opentok-ios-sdk-samples-swift.
Publisher timeout can happen for many reason - access to camera , microphone, networking issues, no media (video/audio) frames received on the peer connection and CallKit delays .
I am assuming you are seeing this issue on using CallKit , if so can you please try our sample app and check if the issue persists there.
https://github.com/opentok/opentok-ios-sdk-samples-swift/tree/main/CallKit
Also iOS version of 2.18 is no longer supported , please use the latest one - 2.25 or 2.24
Thanks
from opentok-ios-sdk-samples-swift.
I got it. So when Publisher timeout then I can re-doPublish it again until it can be published?
@IGitGotIt
Thank you so much
from opentok-ios-sdk-samples-swift.
I got it. So when Publisher timeout then I can re-doPublish it again until it can be published? @IGitGotIt Thank you so much
Yes that would be the suggested way. You can republish , and again after 2 seconds or so, if it failed on the first retry. If it still does not work , on a regular basis, there is something inherently wrong in the app code.
The retry typically helps if it was a network issue or some device media lock on audio/camera working it way out. Else not.
from opentok-ios-sdk-samples-swift.
Related Issues (20)
- FrameMetadata isn't working HOT 2
- Opentok initialization crash on iOS 15 HOT 1
- Crash when Accessing Streams property of OTSession HOT 3
- Mirroring issue is not getting resolve by using Custom-Video-Driver project implementation
- Remain green dot HOT 3
- Sync Custom-audio-driver with Objective C repo HOT 2
- App cannot be run on Simulator due to lack of Apple silicon support HOT 1
- application Crashed HOT 1
- Warning: -[AVCaptureSession startRunning] should be called from background thread HOT 4
- Subscriber Video Enabling Problem HOT 2
- Latency of 10sec between the call of doPublish() and the call of session.publish() HOT 3
- Threading Issues HOT 2
- Session connect memory error access HOT 12
- VonageWebRTC-99.2.39: 1 vulnerabilities (highest severity is: 7.5) HOT 1
- Crash on OTPublisher instance creation HOT 3
- Does not compile for arm64 simulator if the project also uses Swift Package Manager HOT 4
- OTPublisher never be published with internal error from AudioUnitInitialize HOT 9
- How do you stop a Publisher that is not published to a session? HOT 2
- App crash - Attempted to dereference garbage pointer HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from opentok-ios-sdk-samples-swift.