I want to be able to overlay an audio track onto a video all within the Android API. Is this possible?
I'm not sure if that's what you need, but if you're looking for doing this during playback (not changing the actual video file) you can create two mediaplayers, and set the volume of the one that plays video to 0 using setVolume method.
Related
I'm trying to replace the audio of a video in Android.
I think to solutions like mute the video and put on it an audio track, but
that not works very well if you want to save the video with the track on.
Is there a way to replace the sound part of a video to make it savable?
Thanks in advance.
I guess there are easier solutions, but it seems to be possible to use ffmpeg on android (FFmpeg on Android might get you going at installing it). You can then strip the audio (if you have set an audiosource while recording), and add other audio to your video. You can find many example ffmpeg-commands on how to remove from and add audio to your video.
Has anyone tried using ExoPlayer to achieve this?
I tried looking online with no success.
When I say gapless playback, I am referring to the problem of using the media player to play local videos back to back. After the first video is done playing, there is a noticeable delay of 1 second before the second video starts.
Hoping this question helps in understanding this issue further.
For reference please look at the following question:
Android: MediaPlayer gapless or seamless Video Playing
ExoPlayer 2, which is now officially released, seems to support gapless playback using the ConcatenatingMediaSource class. From its developer guide:
Transitions between sources are seamless. There is no requirement that the sources being concatenated are of the same format (e.g. it’s fine to concatenate a video file containing 480p H264 with one that contains 720p VP9). The sources may even be of different types (e.g. it’s fine to concatenate a video with an audio only stream).
And the example code:
MediaSource firstSource = new ExtractorMediaSource(firstVideoUri, ...);
MediaSource secondSource = new ExtractorMediaSource(secondVideoUri, ...);
// Plays the first video, then the second video.
ConcatenatingMediaSource concatenatedSource =
new ConcatenatingMediaSource(firstSource, secondSource);
EDIT: ExoPlayer 2 supports gapless playback, but as of the time of writing is still unreleased as a stable version.
You will most likely never be able to achieve perfect gapless playback of multiple tracks with ExoPlayer or Android Media Player. Neither have been written to support starting multiple tracks and I imagine it will stay out of scope for both of them.
You can achieve gapless playback by using 2 different player instances, once you have started and played the first, you can load the second and start playback once the first finishes. Using this method you could have a gapless solution, as long as you prepare the second video during playback of the first.
To take it further, you can also use 2 different surface textures for rendering the multiple videos, once the first video reaches the end you could fade out the texture and fade in the new one. Resulting in a nice seamless video effect.
Because of the nature of playing multiple videos at once you will most likely want to create your own timer for incrementing the time and deciding when to switch to the next video, rather than trying to use the callbacks from ExoPlayer or Android Media. This will allow you to keep track of the time in a more accurate fashion, without needing to keep talking to multiple video codecs.
I know this is not the answer you've been looking for, but it's the only reasonable answer. The sole way to ensure no gaps in playback is to download the entire file first and begin playback when it's done. Otherwise, in the event that you lose connectivity before the file is finished downloading, pausing is inescapable.
I just tried switching to ExoPlayer from the standard MediaPlayer implementation and the gap is the same if not worse. However I have used a very simple method of restarting the player when the status changes to ended. I don't know if there's a better proper way to do it, perhaps with 2 different ExoPlayers.
This is not a question about playing two separate videos in two separate VideoViews on the one activity.
I have been asked to see if it is possible to create an activity with a single VideoView. When the user opens the Activity, they are asked to select a base video and then select a second video. Both videos will be playing in the one VideoView at the same time, but the base video will have an alpha of 255 and the second video will have an alpha of 150.
For testing though, video files located on the phone will do.
At this time, I have only been able to create an activity that plays a single video in a VideoView.
I thought if I created a custom VideoView class I could override the onDraw function and somehow grab the video frame from the second video, apply alpha and then redraw it over the first VideoView's canvas, but I do not know where to start.
My other concern with this process is the amount of memory used to play two videos at once in the one VideoView as well as the processing required to apply the alpha and then redraw it seamlessly without affecting the performance or playback of the video.
I'm not sure where to start or how best to approach this and if possible, was hoping for some guidance as to either methods or objects to use.
I'm developing a demo application to show the client on an Android 2.2 system using Eclipse. I'm not looking to target any higher systems at this time as the demo phone runs Android 2.2.
I'm not entirely sure why you would want to use a VideoView like that. VideoViews use only one MediaPlayer and using it to sync one video on top of another would probably require a very kludgey implementation of two MediaPlayers through the same VideoView subclass, rendering on the same surface.
Take a look at the source code to see how a MediaPlayer renders a video inside of a VideoView and how MediaController controls playback. You can probably hack around in there to have two MediaPlayers point at once to the same VideoView/SurfaceView. Alternatively you could probably subclass MediaPlayer to handle multiple data sources.
Doing either of these things is counter to what VideoView and MediaPlayer are built for, and performance is going to take a huge hit.
If using a VideoView is not a hard requirement, then my suggestion would be to use an existing video library like ffmpeg, which would be easier and more performant than rewriting base media classes (caveat: using ffmpeg will require the NDK, I suggest using an existing ffmpeg wrapper to save time).
Once ffmpeg is added to your project, applying the secondary video as an OverlayVideoFilter would be fairly easy, and should allow you to layer one video on top of the other (though controlling playback simultaneously might be a challenge left for you).
The correct path to take probably depends on what you want to do with the compound video once you get it (export the video as a single video, control playback, etc.).
Playing two videos in a single VideoView is not possible. This is because the VideoView is in reality an extended SurfaceView, which is both outdated, and never worked super well to begin with. (more on this at the bottom)
I don't know why you have a hard requirement on using a VideoView, as it is very simplistic, and will not give you what you need.
If your requirement for VideoView is because you want to keep the media controls and playback functionality, you're better off making a custom View. Extend LinearLayout and add two SurfaceViews to it with weights of 1. Copy the content of VideoView.java and place it in your new View, and make the modifications to handle two SurfaceViews playing two videos synchronously.
You're actually better off using TextureViews instead of SurfaceViews, which where added in api 14. It rectifies many of SurfaceView's shortcomings, and will handle things like animations better than the VideoView will.
I want to make video player with next option to keep playing video after rotate device.
I created service with MediaPlayer and set SurfaceHolder of SurfaceView after rotate sceen. It works only for Android 4.x. For Android 2.3.X after replace second call setDisplay user doesn't see video, but hears sound of video.
Could you give me direction or example how to implement this option at custom player?
PS. Player shows streaming video.
Okay, I've found solution. It's so easy. I set configChanges="orientation|screenSize" for activity with custom player. In this case activity won't be recreated after rotate device it's changed on the same instance.
As result, I don't need service for keeping MediaPlayer and don't need replace SurfaceHolder.
I would like to know if it is possible to embed the default audio player into one of my activities. Or at least be able to embed the section that has the play/pause button and the audio track seek bar.
The reason I would like to embed it rather than open it in a new intent (like this:
Intent audioActivity = new Intent(Intent.ACTION_VIEW);
audioActivity.setDataAndType(Uri.parse(getAudioURL()), "audio/*");
startActivity(audioActivity);
)
is that I want the users to be able to read some content within the current activity while listening to the audio. I have been able to use a progress bar which updates based on the progress in the audio track, but this does not look good and i would rather have the look and feel of the default audio player. I know the default video/audio players are not documented very well but if this is at all possible I would like to know. Thanks!
Hi, I would like to know if it is possible to embed the default audio player into one of my activities.
No, sorry.
First, there is no such thing as "the default audio player" as a single entity. Each device has its own "default audio player".
Second, even if there were a single universal "default audio player", there is no way in Android to embed some other application's UI into your own.
Or at least be able to embed the section that has the play/pause button and the audio track seek bar.
No, sorry. See above.
I think what you're looking for is MediaController. This answer has a good example of how to use this, though I'm not sure if it is possible to have the controls displaying all the time (they disappear after 3 seconds in the example):
How can I show a MediaController while playing audio in Android?
There's another discussion of it here:
How to implement an audio player for Android using MediaPlayer And MediaController?