How do I prevent multiple Android VideoViews from interfering each other? - android

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!

Related

Keep video playing even on orientation change inside fragment?

A question like this is already posted but in my situation, there is some difference.
I have different layout design for landscape and portrait modes (both modes have VideoView) of the fragment that's why I can not use configChanges as below:
android:configChanges="screenSize|orientation|keyboardHidden"
Now when I rotate everything recreate.
I tried retainState/saveInstanceState but does not get success.
I want my video to play continuously without stopping like YouTube app.
Any help would be appreciated.
If you are using the MediaPlayer classes for video playback I would suggest against doing so. YouTube app uses a library called ExoPlayer that is far superior in terms of video support on Android devices. It is a little harder to get setup and operating but once it is that success in playing videos across all the android devices is much better.
That being said. You will still need to stop the video and resume playing at that specific time frame. The best way to do this would be to get the timestamp on rotation and once the surface being played to is ready again (onSurfaceCreateed or onSurfaceChanged events if using the ExoPlayer library) start the video again at that time stamp.

Android ExoPlayer : Does it solve gapless / seamless playback issue that is broken for the Android Media Player

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.

Play two videos in one VideoView at the same time

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.

Play two Videos at same time

I have an app that shows a dancing toy in a VideoView at full screen. Sometimes another video executes over the video of the toy, in this case i have problems with the view because the video of the top shows transparent.
If i set vid1.stopPlayback(); before call the second video, it works, but i cant reproduce the first.
Is there some way to play both videos at same time?
I am not fully certain, but I got a feeling I've read simultaneous video playback may not be possible due to the way it is rendered on the screen. I can't find where I read about this, but you may try searching that way though.

Smooth transition between different videos using VideoView

I’m trying to achieve the following:
Play a long video from the web using a VideoView
In Parallel buffer a short video from the Web
After X Seconds, pause the long video and Play the short one
When done playing the short video, I resume the long video
I need the transition between movies will be as smooth as possible
I’ve tried to achieve this by several methods using ICS:
Use two VideoViews on top of each other and toggle between them, but I had Z-ordering issues
I’ve took the code of VideoView and modify it to have another MediaPlay inside it to buffer and play the short movie
Option number 2 works on ICS, but when trying on Android 2.3 it failed to work, I’ve read that having two MediaPlay objects running in the same time is not guaranteed to work.
My question is how can this be achieved using Android 2.1 or higher?
The option 1 is never a possiblity as you can not have two SurfaceViews/VideoView z ordered on the same screen.
PFB the link which states the same thing:
Handling two surfaceViews

Categories

Resources