Android : multiple audio tracks in a VideoView? - android

I've got some .MP4 video files that must be read in a VideoView in an Android activity. These videos include several audio tracks, with each one corresponding to a user language (eg. : English, French, Japanese...).
I've got unexpected trouble finding any help or documentation to provide such a feature. I'm currently able to load the video and play it in a VideoView with a MediaController, but not to change audio tracks.
I'm not sure the Android SDK provides any easy way to do this, which leaves me quite clueless on how to solve my problem. I was thinking of extracting every audio track, loading the audio that I want into a MediaPlayer depending on the language, then make audio and video play together. But I fear that some sync issues could arise and prevent me from doing this.
If you have any clue, any advice to help me getting started with this problem, you're more than welcome.

No 3rd party library required:
mVideoView.setVideoURI(Uri.parse("")); // set video source
mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
MediaPlayer.TrackInfo[] trackInfoArray = mp.getTrackInfo();
for (int i = 0; i < trackInfoArray.length; i++) {
// you can switch out the language comparison logic to whatever works for you
if (trackInfoArray[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO
&& trackInfoArray[i].getLanguage().equals(Locale.getDefault().getISO3Language()) {
mp.selectTrack(i);
break;
}
}
return true;
}
});
As far as I can tell - audio tracks should be encoded in the 3-letter ISO 639-2 in order to be recognized correctly.

Haven't tested myself yet, but it seems that Vitamio library has support for multiple audio tracks (among other interesting features). It is API-compatible with VideoView class from Android.
Probably you would have to use Vitamio VideoView.setAudioTrack() to set audio track (for example based on locale). See Vitamio API docs for details.

Now you can Play Multiple audio track through ExoPlayer.
Here is the details,
https://exoplayer.dev/track-selection.html
Exo Player Track Selection

VideoView class can't support your require.U must parse to get audio stream data(you want) to play with AudioTrack class on java layer.

Related

How to control youtube video quality in exoplayer android?

I am working on Android ExoPlayer as mentioned in this Article- https://betterprogramming.pub/android-exoplayer-play-videos-in-your-app-like-youtube-486853913397
But I am unable to control the video quality (360p, 480p, etc). How to do that? I need the complete code.
For ABR streams, ExoPlayer will automatically switch to the best bit rate based on its assessment of current network conditions etc - e.g. if it is playing a high bit rate for a particular piece of content and determines that the network is busy and its buffer is not keeping up, it will switch to a lower bit rate for that content. More info here:
https://exoplayer.dev/track-selection.html
If you mean that you would like to be able to control the bit rate manually, then the track selector functionality will allow you do that.
You can see more info here (linked from the ExoPLayer GitHub): https://medium.com/google-exoplayer/exoplayer-2-x-track-selection-2b62ff712cc9
The default interface looks like:
You can select the quality version by creating your own ABR algorithm, e.g., yourOwnABR(), then call it in the function updateSelectedTrack() of file AdaptiveTrackSelection.java as follows.
public void updateSelectedTrack(
long playbackPositionUs,
long bufferedDurationUs,
long availableDurationUs,
List<? extends MediaChunk> queue,
MediaChunkIterator[] mediaChunkIterators) {
...
int newSelectedIndex = yourOwnABR();
...

How to play Multi Track video file through android MediaPlayer?

I'm working an an App that plays Video files. I'm using android MediaPlayer class to play Video files.
Problem:
I want to play let say a video file with multiple embedded Audio Tracks. And then want to allow users choose between the tracks at runtime through an interface.
Is it even possible with Android MediaPlayer?
I've seen many application that has this feature like MX PLayer, VLC for android ...
Yes Android MediaPlayer supports playback for multiple embedded Audio Tracks.
You can use selectTrack API to achieve the same.
Syntax goes as below.
public void selectTrack (int index)
index int: the index of the
track to be selected. The valid range of the index is 0..total number
of track - 1. The total number of tracks as well as the type of each
individual track can be found by calling getTrackInfo() method.
Example usage:
MediaPlayer mplayer = new MediaPlayer();
MediaPlayer.TrackInfo[] trackInfo = mplayer.getTrackInfo();
for (int i = 0; i < trackInfoArray.length; i++) {
if (trackInfo[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
mplayer.selectTrack(i);
break;
}

Adjust Dash stream volume with Android Exoplayer

I'm trying to set up a seekbar to control the level of an instance of exoplayer streaming dash.
The setup I am using is a modified version of the demo project and am having trouble figuring out which element I should be trying to affect with the seekbars output ie how to use MSG_SET_VOLUME properly etc etc
Any input would be massively appreciated.
The end result I am looking for is an application with two instances of exoplayer both streaming dash content with a fader(seekbar) controlling the mix of the two players (which once this is figured out i presume should be easy enough if the maths is correct)
Again any help would be massively appreciated I have had a bit of a time with Exoplayer so far being such a novice! thanks guys!
If I read the ExoPlayer source code correctly you have to keep references to the audioRenderers you use when preparing the ExoPlayer instance.
exoPlayer.prepare(audioRenderer);
To change volume you have to send the following message:
exoPlayer.sendMessage(audioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME, 0.1f);
First you pass the audioRenderer for which you want to change the volume. Secondly you define the message which you want to send to the renderer which is MSG_SET_VOLUME, since you want to affect audio.
Finally you pass the value you want to set the volume to. In this example I chose 0.1f but of course you can use any value which fits your needs.
You can effect two different playback volumes if you send messages to both MediaCodecAudioTrackRenderers which you used to prepare playback. So you could send two messages with for example value 0.4f for audioRenderer1 and 0.6f for audioRenderer2 to blend the playbacks into one another.
I did not try this myself, but I think it should work.
This is the snippet of the original ExoPlayer code which is responsible for handling the MSG_SET_VOLUME message:
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
if (messageType == MSG_SET_VOLUME) {
audioTrack.setVolume((Float) message);
} else {
super.handleMessage(messageType, message);
}
}

MediaCodec audio/video muxing issues ond Android

I am transcoding videos based on the example given by Google (https://android.googlesource.com/platform/cts/+/master/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java)
Basically, transocding of MP4 files works, but on some phones I get some weird results. If for example I transcode a video with audio on an HTC One, the code won't give any errors but the file cannot play afterward on the phone. If I have a 10 seconds video it jumps to almost the last second and you only here some crackling noise. If you play the video with VLC the audio track is completely muted.
I did not alter the code in terms of encoding/decoding and the same code gives correct results on a Nexus 5 or MotoX for example.
Anybody having an idea why it might fail on that specific device?
Best regard and thank you,
Florian
I made it work in Android 4.4.2 devices by following changes:
Set AAC profile to AACObjectLC instead of AACObjectHE
private static final int OUTPUT_AUDIO_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
During creation of output audio format, use sample rate and channel count of input format instead of fixed values
MediaFormat outputAudioFormat = MediaFormat.createAudioFormat(OUTPUT_AUDIO_MIME_TYPE,
inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE),
inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
Put a check just before audio muxing audio track to control presentation timestamps. (To avoid timestampUs X < lastTimestampUs X for Audio track error)
if (audioPresentationTimeUsLast == 0) { // Defined in the begining of method
audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
} else {
if (audioPresentationTimeUsLast > audioEncoderOutputBufferInfo.presentationTimeUs) {
audioEncoderOutputBufferInfo.presentationTimeUs = audioPresentationTimeUsLast + 1;
}
audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
}
// Write data
if (audioEncoderOutputBufferInfo.size != 0) {
muxer.writeSampleData(outputAudioTrack, encoderOutputBuffer, audioEncoderOutputBufferInfo);
}
Hope this helps...
If original CTS tests fail you need to go to device vendors and ask for fixes

Getting audio volume during playback

I have some audio data (raw AAC) inside a byte array for playback. During playback, I need to get its volume/amplitude to draw (something like an audio wave when playing).
What I'm thinking now is to get the volume/amplitude of the current audio every 200 milliseconds and use that for drawing (using a canvas), but I'm not sure how to do that.
.
.
.
.
** 2011/07/13 add following **
Sorry just been delayed on other project until now.
What I tried is run the following codes in a thread, and playing my AAC audio.
a loop
{
// int v=audio.getStreamVolume(AudioManager.MODE_NORMAL);
// int v=audio.getStreamVolume(AudioManager.STREAM_MUSIC);
int v=audio.getStreamVolume(AudioManager.STREAM_DTMF);
// Tried 3 settings above
Log.i(HiCardConstants.TAG, "Volume - "+v);
try{Thread.sleep(200);}
catch(InterruptedException ie){}
}
But only get a fixed value, not dynamic volume...
And I also found a class named Visualizer, but unfortunately, my target platform is Android 2.2 ... :-(
Any suggestions are welcome :-)
After days and nights, I found that an Android app project called ringdroid
can solve my problem.
It helps me to get an audio gain value array, so that I can use to to draw my sound wave.
BTW, as my experience, some .AMR or .MP3 can't be parsed correctly, due to too low bitrate...

Categories

Resources