I'm implementing a video player with ads. Eventually, playback is paused and some ads are shown, after the ads playback is resumed.
To implement this I've done a FrameLayout with a VideoView and another View to display the ads.
When the ads break is reached I do:
videoView.pause();
videoView.setVisibility(View.GONE);
adsView.setVisibility(View.VISIBLE):
//Play ads for X time
adsView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.play();
It's fairly simple and it works fine in all devices I tried except the Nexus 7.
On the Nexus 7 when playback is resumed the video gets smaller and it doesn't fill the whole screen. It only uses aprox 1/4 of the screen.
After a lot of hours investigating I realised this only happens when I change the visibility of the VideoView. If I comment the following line //videoView.setVisibility(View.GONE); the problem disappears but I can't see the ads.
Some logs that may be relevant:
NvOsDebugPrintf BeginSequence 640x368
NvOsDebugPrintf pnvsi->nDecodeBuffers = 9
NvOsDebugPrintf Display Resolution : (640x360)
NvOsDebugPrintf Display Aspect Ratio : (128x360)
Display aspect ratio (128x360) should be the same as the display resolution (640x360) but it isn't.
Any idea?
Thanks
Not sure of the cause but there seems to be measuring error (I think there are other reports of some measuring issues on n7). View.GONE causes the views to be relaid out to account of the space that is now free from the disappearing view.
As a work around, you can avoid being relaid out -- try placing both views inside a RelativeLayout and have them completely overlap by setting fill_parent on width and height to both. Then you can use setVisibility(View.INVISIBLE) which does not cause the widgets to resize.
Related
I am testing ExoPlayer2 using the google exoplayer-codelab-00 app https://github.com/googlecodelabs/exoplayer-intro . The goal is streaming from an IP camera. I have to rotate the camera video stream from landscape to portrait, shown on device in portrait mode.
I changed surface type to TextureView, in PlayerActivity.initializePlayer set playerView.setRotation(90). The video appears correctly rotated, but it is scaled at the initial size which would have been shown without the rotation, like this.
I tried changing width and height in playerView.getLayoutParams() + playerView.setLayoutParams(), but the video is never shown higher. Change of RESIZE_MODE_FIT to RESIZE_MODE_FILL just expands the video to fit the new width, but the height is not changed, like this.
Setting player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT) makes no difference either.
IMO some layer of the view stack does not get rotated with the playerView.setRotation(90) and the unrotated dimensions somehow constrain the rotated video. I want the rotation fixed, it is called before setting media item. The device will always be positioned in portrait mode (fixed installation). Thanks a lot for any hints, I am completely new to Android.
I'm playing a Full HD video inside a VideoView, but my screen size is just 1216px x 684px.
The VideoView is cropping the video, but I want it scaled down. I found one "bug" that makes what I want, but surely it's not the best way. If I set 1px margin around the VideoView, it scales correctly.
The VideoView is inside a RelativeLayout, I tried to set centerInParent, "alignParentLeft, Right, Top and Bottom" but none of this works.
Is there another way to make VideoView correctly scale the source?
Another issue:
When I pause my VideoView, it goes dark, instead of freezing the image. Is there a way I could achieve this behavior?
Thanks in advance for every reply.
I have a webview and it displays a video link over the internet. Bu when the video was loaded it scales the view bigger than my linearlayout. But I want it fit into my linear layout. I've tried some methods like LayoutAlgorithm.SINGLE_COLUMN or writng the scale property manually but I couldn't find the right solution.
How can I scale it dynamically?
You may like to try setInitialScale ( http://developer.android.com/reference/android/webkit/WebView.html#setInitialScale(int) ). This will help to "zoom" the page (or the video) shown in the Webview to fit a particular width. Actually the size of HTML5 video in that page is decided by webkit engine and we cannot directly change its size from App layer.
You may also want to calculate the expected width yourself, due to the fact that Android devices have hundreds of screen resolutions and the width of your LinearLayout may vary on defferent devices.
everyone. I have a project where I need to display a video within a VideoView in portrait orientation, but I've been running into a weird issue for the last couple weeks. Also note, this issue only occurs the first time the VideoView is loaded with data.
This is a very stripped version of the layout:
<RelativeLayout>
<RelativeLayout>
<VideoView /> <-- W:fill_parent, H:wrap_content
</RelativeLayout>
</RelativeLayout>
Now for the actual issue: when the VideoView is first loaded with data, both its height/width fill the entire screen (minus the padding space) for less than a second (up to 3 seconds, depending on whether it's local or streaming), then it magically adjusts itself to the intended size.
Since it takes longer for videos not stored locally, I feel as if the issue has to do with the VideoView taking time to load the video, and not adjusting its boundaries correctly immediately, which is why it expands to fill the screen, then suddenly drops down to the appropriate size.
Now, I believe the reason it doesn't do that every time is because it's still using the same instance of the VideoView each time it's loaded (since it's using a ViewFlipper and not setContentView, it's not creating a new instance of it).
However, I'm loading the data into the VideoView in the same way, and I don't understand why the issue doesn't persist, which makes me think my assumption of why it's doing that is wrong.
Now for what I've tried:
I started with a width of fill_parent and height of wrap_content for both the RelativeLayout and the VideoView, which is where I noticed this problem initially. Also note: the graphic layout in Eclipse shows the same issue with these settings that I'm trying to solve: the VideoView is expanded to fill the screen, minus the padding it has).
I've tried forcing the layout to a specific pixel dimension in the XML layout (terrible, I know), and then defining new LayoutParams for the views and setting them after the video has been properly loaded.
I've tried creating a new VideoView dynamically and adding it to the layout after it's been loaded; still no luck.
And now I'm out of ideas... Anyone else have some?
And thanks in advance for your help~
EDIT:
As a workaround in the meantime, I created an onPreparedListener() for the VideoView, and keep the view hidden until the onPreparedListener is fired off. That seems to solve the problem, but I'm more curious as to why the VideoView was doing what it's doing, not necessarily just how to fix it.
Thanks again~
I am trying to play a videoview on top of another video view. The first video view is paused, while the second is playing. It appears to work but no second video appears on the screen (though I hear the audio and see the controls that would normally appear on top). I am assuming this is some sort of order issue. Any thoughts. By the way, I have no problem displaying other views on top of the main video view and having the video fill the background.
That won't work - the VideoView is special in the sense that it 'punches' a hole in the normal Views to allow direct access to the display pixels (or, in android terms, the 'Surface' - VideoView is a subclass of SurfaceView). You cannot layer two SurfaceViews on top of eachother - the first one that grabs the pixels (the Surface) will 'own' it. (see SurfaceHolder.Callback.surfaceCreated() / surfaceDestroyed())
Other Views on top of a SurfaceView do work, because the framework will compose the display bits of normal Views on top of the Surface. It cannot do that with another VideoView (i.e. a SurfaceView) because there is nothing to compose.
<VideoView android:id="#+id/videoView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<VideoView android:id="#+id/videoView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
when videoView2 starts playing setvisibilty of videoView1 invisible.
then you can make it visible when you need.
Use Thread to control both video
I don't know if this is helpful at the moment, but I managed to get something similar to what you want...
I needed to nest a VideoView on top of a SurfaceView; as long as they don't overlap 100% it can work. (what i mean is, my surfaceview is the whole screen and videoview is just a small portion of the screen)
The thing is - since you can't compose SurfaceViews, the first one to grab the pixels is the one that will be shown. Intuitiveness will drive you to Z-order your prioritized view AFTER the less-important one in the XML - but as I've said previously, the first one to grab the pixels stays, so make sure you define the smaller view FIRST, and then overlay it with the bigger one.
This will result in such behaviour that the smaller (in my case preview view) acquires the said X * Y pixels, and then the 'background' surfaceview (which is supposed to be on top of it according to the XML) takes up the rest and ignores the smaller surface.
I'm not too sure about handling events from those two though as I only have to play streams in those two views and not react to any kind of clicks/events generated by those two components, but it might be expected that if you followed this route - the bigger view will intercept all clicks made in the smaller view area (because it's on top according to the XML) so maybe you have to programatically move it on top as well upon creation.
Hope it helps.
EDIT:
Although... it like it just works once. It's a work in progress really. Upon returning from any activity, there's nothing i can do to prevent the bigger view claiming everything :/
you can add videoview a on top videoview b,like this,
parentview.removeview(a);
parentview.removviewe(b);
parentview.addview(a);
parentview.addview(b);
parentview.invalidate();
Ti's work for me. I hope it can helps.