I'm looking for a solution to continue playing a video for a URL (*.mp4/playlist.m3u8) in an embedded VideoView on a tablet when the device is rotated.
Currently, the video is being restarted on rotation using onPause() and onResume().
As I understand it, a lot of solutions require using android:configChanges="orientation|screenSize", but Android's developer site suggests using this only as a last resort.
See Handling Runtime Changes.
This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
Is there another way to do this? How would I go about keeping the video playing through rotation like how a Phone device does when using Intents?
Edit: I also want to mention that the other reason I am avoiding use of android:configChanges is because I have different layouts for landscape and portrait, and I do not wish to handle the layout changes manually.
Edit 2: I have come up with a way to get configChanges to work when using different layouts by using SurfaceView within the layouts and handling the layout change in onConfigurationChanged with setContentView and MediaPlayer to switch its display when the layout is changed.
Now, I just need a way to retain the MediaPlayer across orientation changes.
Related
I was trying to use SurfaceView and MediaPlayer to Display video on Android.
I got a bug now that if I press the power button to lock the screen and then unlock it, The Video displayed on the MediaPlayer is gone and there is only sound. Normally for this situation the surfaceView would be somehow freeze to the last frame of the video before I lock the phone.
It works fine when I hide the screen(such as go to home and open another application) But it just does not work when I lock the phone. I think they both pass the onPause and onResume so I do not understand why would there be different logic.
I'd like to know if there is a solution to solve my problem.
Thanks!
I'm not sure exactly what's going on, but there's a general class of problem that is likely the cause of your trouble.
If your lockscreen is orientation-independent, or wants to be oriented the same way the device is, then the Activity won't be restarted to change orientation. In this case, turning the display off and back on with the power button won't cause the SurfaceView's surface to be destroyed. So if your app is relying on the surfaceCreated and surfaceChanged callbacks to fire to make things happen, then things won't happen.
If you leave the Activity and come back, the Surface does get destroyed and re-created.
The relationship between the Activity lifecycle and the Surface lifecycle is a bit complicated; you can find some notes about it in this article, including two basic patterns for structuring an app. Examples of both "styles" of SurfaceView management can be found in Grafika.
I can't make specific recommendations without knowing how your app works, but mainly you just need to look at what your app does with the idea that Activity and Surface lifetimes are not tightly coupled.
OK, I fix this in a weird way, I think it is probably a bug of Android. Don't have time to do enough testing on this.
First surely as #fadden says you need to have a mMediaPlayer.setDisplay(myHolder) elsewhere not in the surfaceChanged or surfaceCreated since they may not be called while resume from locked screen.
For me the problem still persist after I changed it this way. Here is what I changed that solved the problem: Instead of mMediaPlayer = new MediaPlayer(), we should use mMediaPlayer = MediaPlayer.create(MediaActivity.this, fileUri)
I have an android app with a RelativeLayout, to which I programmatically add multiple VideoViews, all of which are playing at the same time. The VideoViews can be moved around by dragging, and they can be moved so that they overlap.
The problem is that I cannot find a way to change the z-order of them during the runtime. .bringToFront() brings the view to front for receiving touch events, however the order of the actual videos remains the same.
I have tried removing and re-adding the videoView by .removeChild(), however that stops and resets the video.
Is there a way to change the z-order of the videos? A "hacky" way would work too, e.g. removing ad re-adding the view without stopping and resetting the video.
Thanks
P.S. It's a streaming video, so restarting the video to the same position would not work, there would be way too big delay.
EDIT: Even though people suggest multiple VideoViews should not work, they do work great, even overlapping, at least on my Nexus S, ICS 4.0.3
EDIT 2: Actually, not great, the second video sometimes flickers, but that's fine for this purpose. The 3rd and 4th video don't flicker, which is a bit weird
The document says the Z-order of SurfaceView's are determined before they are attached to window, and their orders are not altered once attached. Since VideoView's are also SurfaceView, I don't think it is possible to do it.
The VideoViews use SurfaceView, witch is Z-ordered with the windows, but you cannot have multiple SurfaceView z-ordered,because every SurfaceView will punches a hole on the window. If you add multiple video on the same area, video will not play correctly. I used to translate video out off the screen to keep its state. Look for EcoNews aap on google play.
I want to write an activity that:
Shows the camera preview (viewfinder), and has a "capture" button.
When the "capture" button is pressed, takes a picture and returns it to the calling activity (setResult() & finish()).
Are there any complete examples out there that works on every device? A link to a simple open source application that takes pictures would be the ideal answer.
My research so far:
This is a common scenario, and there are many questions and tutorials on this.
There are two main approaches:
Use the android.provider.MediaStore.ACTION_IMAGE_CAPTURE event. See this question
Use the Camera API directly. See this example or this question (with lots of references).
Approach 1 would have been perfect, but the issue is that the intent is implemented differently on each device. On some devices it works well. However, on some devices you can take a picture but it is never returned to your app. On some devices nothing happens when you launch the intent. Typically it also saves the picture to the SD card, and requires the SD card to be present. The user interaction is also different on every device.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
I would have used ZXing as an example application (I work with it a lot), but it only uses the preview (viewfinder), and doesn't take any pictures. I also found that on some devices, ZXing did not automatically adjust the white balance when the lighting conditions changed, while the native camera app did it properly (not sure if this can be fixed).
Update:
For a while I used the camera API directly. This gives more control (custom UI, etc), but I would not recommend it to anyone. I would work on 90% of devices, but every now and again a new device would be released, with a different problem.
Some of the problems I've encountered:
Handling autofocus
Handling flash
Supporting devices with a front camera, back camera or both
Each device has a different combination of screen resolution, preview resolutions (doesn't always match the screen resolution) and picture resolutions.
So in general, I'd not recommend going this route at all, unless there is no other way. After two years I dumped by custom code and switched back to the Intent-based approach. Since then I've had much less trouble. The issues I've had with the Intent-based approach in the past was probably just my own incompetence.
If you really need to go this route, I've heard it's much easier if you only support devices with Android 4.0+.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
Either there is a bug in the examples or there is a compatibility issue with the devices.
The example that CommonsWare gave works well. The example works when using it as-is, but here are the issues I ran into when modifying it for my use case:
Never take a second picture before the first picture has completed, in other words PictureCallback.onPictureTaken() has been called. The CommonsWare example uses the inPreview flag for this purpose.
Make sure that your SurfaceView is full-screen. If you want a smaller preview you might need to change the preview size selection logic, otherwise the preview might not fit into the SurfaceView on some devices. Some devices only support a full-screen preview size, so keeping it full-screen is the simplest solution.
To add more components to the preview screen, FrameLayout works well in my experience. I started by using a LinearLayout to add text above the preview, but that broke rule #2. When using a FrameLayout to add components on top of the preview, you don't have any issues with the preview resolution.
I also posted a minor issue relating to Camera.open() on GitHub.
"the recommended way to access the camera is to open Camera on a separate thread". Otherwise, Camera.open() can take a while and might bog down the UI thread.
"Callbacks will be invoked on the event thread open(int) was called from". That's why to achieve best performance with camera preview callbacks (e.g. to encode them in a low-latency video for live communication), I recommend to open camera in a new HandlerThread, as shown here.
I'm using a VideoView to play a mp4 file in my application. Is there a way to save all the content that was buffered so when the orientation of the screen is changed the user doesn't have to wait another 10 seconds or more for the video to start playing again.
Perhaps "saving the buffered video" isn't the right solution, I'm just looking for a way to have the playback almost appear seamless when the orientation of the screen is changed.
I'm already saving the video positioning and using the "seekTo" method to start the video where it left off. But I'm looking to prevent the rebuffering as well. I searched all over stackoverflow and couldn't find any discussions on this.
Thanks!
Bradley4
You could handle the configuration change yourself so that the application isn't restarted.
Another solution might be to put the VideoView into a Fragment. Then rather than killing the Fragment with the Activity, you might just pause the video detach the Fragment and re-attach after the configuration change. Although now that I think about it, I think the Fragment may also be re-created on the configuration change...
Very interested in how you solve this, please post your solution if no one answers.
This a general query.
I will be beginning to port a portrait-only app to work for both landscape and portrait screen orientations.
Is there any document that addresses this process specifically?
I will be using native views - so i am not expecting any issues with any resources files such as drawables, etc
I do have one screen in the application that plays video clips - my fear is how to make the video to keep playing while the orientation changes.
Also, wondering if i will have to save any activity states/variables while orientation occurs.
So, these are some of my concerns and i was wondering if there are any thumbrules or documentation i could read up on before plunging into porting.
Thanks in advance.
You should read application fundamentals and what happens while orienting the application. http://developer.android.com/guide/topics/fundamentals.html
If you want a faster orientation change you can read this document http://developer.android.com/resources/articles/faster-screen-orientation-change.html
If you keep your variables static in activity than you can get them in which method you want automatically.