How select audio channel from MP4 file using IMediaReaderActionNotify interface

https://www.wowza.com/docs/how-to-select-audio-data-and-or-video-channel-from-a-multi-channel-mp4-file-by-using-imediareaderactionnotify

Hello,

First of all: thank you very much for implementing this feature; it works brilliantly.

If I may, I would like to pose a small design question though, as to how the correct track index should be determined.

In the way we see it, a video-on-demand recording can have several video- (i.e. different qualities, camera angles, …) and audio-tracks (i.e. different qualities, languages, commentary tracks, …). We then have a consistent mapping between a certain specific track and an MP4 track identifier (an integer value which, I believe, is contained in the tkhd box within the trak box). For instance, the commentary track in the medium quality in the french language might have track identifier 5. If no such track exists for a specific recording, it has no track with identifier 5.

Additionally, I do not believe that the tracks in the MP4 header are in some way ordered by their track identifier. In other words: for each recording, the track with a certain track identifier will appear on some random other position in the list of tracks.

Both of these issues seem to make it difficult to consistently select the proper track based on an index into the total number of tracks.

Do you see this differently?

In any case, making selection based on track identifiers work seems simple enough; an extra method which returns the MP4 track identifier for a given track index should make this work perfectly.

Thankyou, once again,

With kind regards,

Olivier Verhoogen.

I think it will work with live stream if there are multiple audio channels. But I don’t think it will work with flv files

Richard

I don’t know if that is possible.

Richard

Are you asking about choosing between video tracks? I don’t think that is possible. This method is only concerned with audio tracks.

I don’t think you can switch audio tracks midstream.

Richard

Obviously you can record multiple audio tracks and, using this technique, stream one or another by specifying which track in the NetStream.play command. You should be able to use NetStream.play2 command to do switching, and specify a different track in the newStream:

http://livedocs.adobe.com/flex/3/langref/flash/net/NetStreamPlayOptions.html

Richard

This will not work with flv container.

Richard

Sounds good. If it works it works.

Richard

Hi all,

I tried to use this module for choosing audio for live streaming.

I am not sure I got all correct with setup of encoder but it does seem to work with the following command:

ffmpeg -y -i my.vob -i my2.vob -acodec libfaac -ar 44100 -ab 16k -vcodec libx264 -vpre baseline -b 100k -s 240x136 -refs 2 -me_method umh -subq 6 -trellis 0 -g 250 -i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -keyint_min 25 -sc_threshold 40 -level 30 -f flv rtmp://10.0.0.140:1935/live/test -map 0:0 -map 0:1 -map 1:1 -acodec libfaac -ar 44100 -ab 32k -newaudio

My first concern is that only 1 of the module method gets called when I start flash player to play this stream.

This is the log of Wowza:

INFO session connect 10.0.0.10 -

INFO stream create - -

INFO server comment - ModuleMediaReaderNotify.play: test?audioIndex=1

INFO server comment - audioIndex: 1

INFO stream play test -

Looks like module is only notified for play event. Is this correct?

Is it maybe the case because I stream from ffmpeg in FLV container?

For example when using the module for VOD I can see in wowza log all of this:

INFO stream create - -

INFO server comment - ModuleMediaReaderNotify.play: mp4:mux-test.mp4?audioIndex=1

INFO server comment - audioIndex: 1

INFO server comment mux-test.mp4 ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderCreate

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderInit: mux-test.mp4

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderOpen: mux-test.mp4

INFO server comment - audio[0]: trackId:3 lang:eng more:QTAtomtkhd {type:tkhd, offset:16611, size:92 trackId:3 duration:29491 creationTime:Wed Sep 29 15:25:14 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:0 trackHeight:0}

INFO server comment - audio[1]: trackId:4 lang:eng more:QTAtomtkhd {type:tkhd, offset:20589, size:92 trackId:4 duration:73212 creationTime:Wed Sep 29 15:25:14 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:0 trackHeight:0}

INFO server comment - video[0]: trackId:2 width:768 height:432 more:QTAtomtkhd {type:tkhd, offset:165, size:92 trackId:2 duration:29479 creationTime:Thu Apr 08 10:12:40 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:768 trackHeight:432}

INFO server comment - audioTrackSelect: 1

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderExtractMetaData: mux-test.mp4

      • mux-test.mp4 -

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderCreate

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderInit: mux-test.mp4

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderOpen: mux-test.mp4

INFO server comment - audio[0]: trackId:3 lang:eng more:QTAtomtkhd {type:tkhd, offset:16611, size:92 trackId:3 duration:29491 creationTime:Wed Sep 29 15:25:14 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:0 trackHeight:0}

INFO server comment - audio[1]: trackId:4 lang:eng more:QTAtomtkhd {type:tkhd, offset:20589, size:92 trackId:4 duration:73212 creationTime:Wed Sep 29 15:25:14 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:0 trackHeight:0}

INFO server comment - video[0]: trackId:2 width:768 height:432 more:QTAtomtkhd {type:tkhd, offset:165, size:92 trackId:2 duration:29479 creationTime:Thu Apr 08 10:12:40 CEST 2010 modificationTime:Wed Sep 29 15:25:15 CEST 2010 trackWidth:768 trackHeight:432}

INFO server comment - audioTrackSelect: 1

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderExtractMetaData: mux-test.mp4

INFO server comment - ModuleMediaReaderNotify#MediaReaderListener.onMediaReaderClose: mux-test.mp4

INFO stream unpause mux-test.mp4 -

INFO stream play mux-test.mp4 -

Does this also work for live streams and flv files?

Hi Richard,

using the same kind of implementation do you by any chance see a way to chose between the right track and the left track of a stereo audio channel ?

The final point would be to implement an “audio balance” on the server side, where the only possibilities would be :

  • Play Stereo

  • Play 100% Left Channel - 0% Right Channel

  • Play 100% Right Channel - 0% Left Channel

Thanks a lot.

Cheers,

Louis

Does this also work for live streams and flv files?

Dear ertu22, rrlanham,

Not at all pretending to know anything much about this:

Looking at the MediaReaders.xml configuration file it would seem that the MediaReaderH264 class is associated specifically with the MP4 file format.

Using Eclipse’s content assist I cannot see similar methods for the MediaReaderFLV class. I’m not sure that the FLV container format can cope with multiple video and audio tracks to begin with.

Olivier.

Hello,

As an FYI (and a concealed coinciding question :)): This method also works splendidly for Silverlight smooth streams.

For this we do have to parse the selected tracks in the ‘onHTTPSmoothStreamingSessionCreate’ method – the smooth streaming counterpart of the ‘play’ method.

While implementing this I could not find something similar to Client properties for Silverlight; I now pass the selected tracks to the IMediaReaderActionNotify implementation instance via a shared ThreadLocal object. This assumes of course that when a ‘play’ or a ‘onHTTPSmoothStreamingSessionCreate’ happens, the listener is always invoked in the same thread. Could someone perhaps confirm that this always holds?

Or perhaps someone knows of a better way to communicate this information to the listener, which will also work for Silverlight?

Cheers!

Olivier.

Hello,

First of all: thank you very much for implementing this feature; it works brilliantly.

If I may, I would like to pose a small design question though, as to how the correct track index should be determined.

In the way we see it, a video-on-demand recording can have several video- (i.e. different qualities, camera angles, …) and audio-tracks (i.e. different qualities, languages, commentary tracks, …). We then have a consistent mapping between a certain specific track and an MP4 track identifier (an integer value which, I believe, is contained in the tkhd box within the trak box). For instance, the commentary track in the medium quality in the french language might have track identifier 5. If no such track exists for a specific recording, it has no track with identifier 5.

Additionally, I do not believe that the tracks in the MP4 header are in some way ordered by their track identifier. In other words: for each recording, the track with a certain track identifier will appear on some random other position in the list of tracks.

Both of these issues seem to make it difficult to consistently select the proper track based on an index into the total number of tracks.

Do you see this differently?

In any case, making selection based on track identifiers work seems simple enough; an extra method which returns the MP4 track identifier for a given track index should make this work perfectly.

Thankyou, once again,

With kind regards,

Olivier Verhoogen.

I am also interested in this subject.

Also, would I be able to switch audio index through client calls?

This might then be our way to go for realtime audio/language switching without syncing issues.

nobody? :confused:

Are you asking about choosing between video tracks? I don’t think that is possible. This method is only concerned with audio tracks.

I don’t think you can switch audio tracks midstream.

Richard

Hi Richard,

Yes, I was talking about video streams.

I got the impression that it was possible to encode multiple audiotracks in one videofile. I then got to wonder if it were possible to switch between these audiotracks at runtime.

Right now we are combining an mp3-stream and a h264 stream client-side and correcting for differences of more than 200ms. This however doesn’t seem like the most sophisticated way of syncing audio with video.

Come on you guys… we chose wowza because it’s the best!

There has to be a way to mux audio and video server-side :rolleyes:

Daniel