I am striving to create a simple Android media player that can play multiple videos simultaneously on a single screen. So basically a single media player screen is divided into multiple parts, and each part plays a given video. Is it feasible to do it within current Android API? Or is there any existing Android sample/library or anything that can do that? If we need to use multiple media players glued together, we should make sure there is no bordering or edges as if it is whole a single media player. Of course a limited number of videos are expected to play.
A neat and ideal call of such player can be similar to Android's default mediaplayer and extends it given multiple media inputs, such as
MultiMediaPlayer mmp = new MultiMediaPlayer ();
mmp.add(video1,0,0,50,50);
mmp.add(video2, 51, 51, 100, 100);
...
It's possible, I am afraid there is no support natively from Android. But you have to instantiate multi players and take care of display window management.
Related
I'm working on a project that use Exoplayer2 for HLS video streaming. Adaptive streaming is working well in my exoplayer, but i want to implement a feature that user can change the resolution (144p,240p,480p..)of the video manually from UI. I got the resolution of the playing video from TrackGroup API. But don't know how to set the resolution value into the playing video manually.
Thanks
You can do this using the track selector functionality in Exoplayer2 - it essentially limits the tracks that the adaptive bit rate selection functionality in the player can select from.
It can only select from the available tracks in the stream index file, the manifest file. Hence, your choice of resolutions/bit rates is limited to whatever bitrate, resolution etc the stream provider has made available - i.e. the user can't just choose an arbitrary bit rate or resolution that they would like, if it is not one of the available ones in the manifest file (the video track index file).
To have just one track you simply only allow that one.
This functionality is included in the demo - here is an example screen shot from one of their blogs about this:
More details specifically on track selection here (it is also linked from the Exoplyar GitHub page): https://medium.com/google-exoplayer/exoplayer-2-x-track-selection-2b62ff712cc9
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 use my media controller instead of build-in one of YouTube Android Player. So, I have put some views overlapped YouTube Android Player. However, I got a problem which is it always pauses automatically after played one second. Therefore, is it possible to overlay some views on YouTube Android Player?
Youtube deliberately prevent any attempt at displaying anything on top of their player.
As soon as it detects this the playback will pause.
This blocks the growth of a whole industry of video meme players :(
One main reason for this could be to prevent the obvious attempt at competing with Google for advertising space and other imaginable features that capitalize on video material published by users.
The YouTube provided player is intended to be the only possible path to accessing Youtube content.
The initial (now deprecated) Youtube API was much more liberal and allowed listing of all encoded quality versions of a clip and direct streaming of it to your own VideoView based player. This was an open path to all kinds of misuse and violations so they scrapped that in favor of a controlled solution where the Youtube player is the gateway that control how playback can occur.
The new API at least allows the player to be controlled such as seeking to a specific position and to query current position. For some apps that is hot enough a possibility for coming up with new end user value.
In my app, I use several independent VideoViews in order to buffer videos one after another while only one video is playing at the same time.
I observed that when one video is playing and I call VideoView.setVideoURI on a VideoView in the background in order to start buffering, the currently visible video will suddenly be cropped to the dimensions of the video that is loading in the background.
I assume that this is a low-level bug within the Android system which will crop the existing video rendering layer as soon as there's new video data available, even if both videos and VideoViews are actually independent.
Has anybody also noticed this behaviour and knows a workaround?
Thanks!