Are there any live audio streaming examples for the mobile sdk now that support for this has been added in the 2019 R3?

Sorry all should have added this before…

Specifically with relation to Android

Hi,

At the moment, we don’t have live audio sample for Android mobile SDK - we only have Push-to-talk sample (which is pushing audio from the client to the server)

We do have live audio sample for iOS, maybe it could still be useful to you?

Best regards,

Plamen Parvanov

Whilst the iOS examples helps find the correct commands ‘requestAudioStream’ ‘closeAudioStream’

It does not really help with the actual playback as the player is obviously specific to iOS.

Is this code

    func requestAudioSuccessHandler(_ response: XPSDKResponse) {
        let url = XPSDKConnection.sharedConnection.url
        let urlProtocol = (url?.scheme)!
        let host = (url?.host)!
        let port = (url?.port)!
        
        let outputParameters = response.parameters
        audioId = outputParameters!["VideoId"] as! String
        let audioURL = String(format: "/%@/Audio/%@", (XPSDKConnection.sharedConnection.serverInfo?.serviceAlias)!, audioId )
        fullURL = String(format: "%@://%@:%u%@", urlProtocol, host, port, audioURL)
        isStoppedIntentionally = false
        self.playAudio(forURL: fullURL)
    }

Simply creating a URL and passing it to an audio player? I cannot find any documentation for how the audio frames are provided, your own app appears to be using com.google.android.exoplayer2 expecting an MP3 stream?

If you have an equivalent of AudioManager.swift in Java or Kotlin, even without a fully worked app example that would be really helpful.

Thanks

Hi,

Audio is not provided in frames but as a stream, so yes, simply creating an URL and passing it to the player will work also for Exoplayer. The mobile server will start streaming the audio data and the player will play it.

Some code like this should work:

SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl);

DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, … );

Uri mp3_URI = Uri.parse(streamURL);

MediaSource audioSource = new ExtractorMediaSource(mp3_URI, dataSourceFactory, new DefaultExtractorsFactory(), null, null);

player.setPlayWhenReady(true);

player.prepare(audioSource);

… and don’t forget to close the audio stream when finished:

xProtectSDK.stopAudioStream(streamId, … )

Best regards,

Plamen Parvanov

Thank you. Have got audio playing now.

For anyone else reading this, vProps is needed in the requestAudioStream method, with a minimum of AudioEncoding = Mp3 or the method will return code 14 (Wrong input parameter)

val props = HashMap<String, String>()
props["StreamDataType"] = "Audio"
props["AudioEncoding"] = "Mp3"
props["StreamHeaders"] = "NoHeaders"
 
xpMobileSDK!!.requestAudioStream(micId, null, props, "Live", "Push", {
    if (it.outputParam.size > 0) {
        var streamId = it.outputParam["StreamId"]
        val protocol = if (xpMobileSDK?.session?.isSecureConnection!!)
            "https"
        else
            "http"
        val host = xpMobileSDK?.session?.serverHost
        val port = xpMobileSDK?.session?.serverPort
        val serviceAlias = xpMobileSDK?.session?.serverAlias
        val url = "$protocol://$host:$port/$serviceAlias/Audio/$streamId"
 
        (context as Activity).runOnUiThread {
            AudioManager.play(context, url)
        }
    }
}, Log.e(TAG, it?.errorCode) })

Hello People,

I will try using this example but I have a problem with AudioManager.play, (see Attach). Do you have any idea about this issue in my code? Do you have any implementation regarding the AudioManager to use the play method?

Thanks,

Dario

Dear Jon, I have replicated your code but I have error in requestAudioStream: Error code 54.

The Code:

private fun requestAudio(fqid: String, videoId: String, response: CommunicationCommand) {

val audioProps = HashMap<String, String>()

audioProps\["StreamDataType"\] = "Audio"

audioProps\["AudioEncoding"\] = "Mp3"

audioProps\["StreamHeaders"\] = "NoHeaders"

xpMobileSDK!!.requestAudioStream(fqid, null, audioProps, "Live", "Push", **{** communicationCommand **\->**

    if (communicationCommand._outputParam_.size > 0) {

        val streamId = communicationCommand._outputParam_\["videoId"\]

        val protocol = if (xpMobileSDK!!._session_._isSecureConnection_) "https" else "http"

        val host = xpMobileSDK!!._session_._serverHost_

        val port = xpMobileSDK!!._session_._serverPort_

        val serviceAlias = xpMobileSDK!!._session_._serverAlias_

        val url = "$protocol://$host:$port/$serviceAlias/Audio/$streamId"

        runOnUiThread **{**

            audioManager.play(context,url)

        **}**

    }

**}**) **{** communicationCommand **\->** Log.e("ERROR AUDIO MANAGER", communicationCommand._error_) **}**

}