SurfaceView crops content unpredictably - android

Im developing video app for TV boxes. For SurfaceView (shows video from android MediaPlayer) with "stretch vertically" display mode the same coordinates for both boxes are calculated by algorythm. For example result is: left: -960, top: 0, right: 960, bottom: 1080, then it passed to the mySurfaceView.layout(left, top, right, bottom).
On two different boxes (both android 7 and one resolution 1920x1080) I have different behavior: the first crops picture (I need this behavior)
and the second compresses picture.
layout:
<FrameLayout >
<custom RelativeLayout match_parent>
<SurfaceView by addView() />
<RL/>
<FL/>
tried:
clipChildren = false for all parent views
mediaPlayer.setVideoScalingMode(...with_cropping)

Related

Android - How add a Large GLSurfaceView in a FrameLayout center?

I am using two GLSUrfaceView to render video of my own camera and video i receive from server. They are video call data. One small and one large in size. The large GLSurfaceView has two mode, one is Normal Screen mode which is done by filling screen width and calculating the screen height as (DISPLAY_WIDTH * ASPECT_RATIO_OF_IMAGE), and the second mode is full screen mode which is done by filling screen height and calculating the screen width as (DISPLAY_HEIGHT * ASPECT_RATIO_OF_IMAGE). I make the screen large on double tap and again normal in double tap again. But the problem is in large mode the image is cut in the right side only. I want my image to be cut in all side fitting the FrameLayout center at GLSurfaceView center. I am adding my Code part also. See the below image also which describe my need.
<RelativeLayout
android:id="#+id/video_call_views_container_outgoing"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/largeGLSurfaceViewContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"/>
<FrameLayout
android:id="#+id/smallGLSurfaceViewContainer"
android:layout_width="120dp"
android:layout_height="170dp"
android:orientation="vertical"
android:visibility="gone"/>
</RelativeLayout>
Here is my coding part :
GLSurfaceView frontCameraGLView = new GLSurfaceView (this);
GLSurfaceView opponentCameraGLView = new GLSurfaceView (this);
largeVideoRenderLayoutOutgoing.addView(opponentCameraGLView );
largeVideoRenderLayoutOutgoing.setOnClickListener(this);
opponentCameraGLView.setZOrderMediaOverlay(false);
smallVideoRenderLayoutOutgoing.addView(frontCameraGLView );
smallVideoRenderLayoutOutgoing.setOnClickListener(this);
largeVideoRenderLayoutOutgoing is the reference of FrameLayout having id largeGLSurfaceViewContainer , smallVideoRenderLayoutOutgoing also refer FrameLayout having id of smallGLSurfaceViewContainer. GLSurfaceView are added to FrameLayout's during onCreate of Activity. The problem is specified in the below image's
This image is image in the Upeer side is in Normal Mode. And the Below image is in Full Screen Mode. See the left side of these image. They are same but the right is cut in FullScreen mode i mean the last image. I wish that the image should be center fitted so that the image is cut in all side focusing my incoming video's center
If a GLSurfaceView's width is or height is larger than the device screen, it will behave like below:
1. For width larger than device width but height is same as device height: the GLSurfaceView will start drawing from top left corner which co-ordinate will be (0,0) and the extra image will be out of screen right side. So the image center will not be in layout's center. To solve this problem we need to shift image left as leftMargin which value will be half of (imageWidth-deviceWidth). The code's are like
ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) glSurfaceView.getLayoutParams();
int margin = (-1 * (int) ((glSurfaceView.getWidth() - displayWidth) / 2));
marginLayoutParams.setMargins(margin, 0, 0, 0);
setLayoutParams(marginLayoutParams);
Please do write a similar code if the heigh of the glsurfaceview is larger than device height. Add a margin on top so that the image is fitted in center of the device

Android FrameLayout position VideoView element by left top width and height

I need to position VideoView element:
Left: 626dip
Top: 86dip
Width: 575dip
Height: 326dip
So when apk start it is in upper right corner...when i press OK button on remote controll it needs VideoView to be in FullScreen (Left: 0, Top: 0, Width: 100%x, Height: 100%y)
How can i make this in xml file?
I im using:
android:layout_gravity="center"
So that VideoView Video fill parent and Video is scalled to parent size.
Here is code that i try but it is centered FullScreen and when i press OK button it is centered SmallScreen, and don't know how to set it Left And Top using dp?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<tv.danmaku.ijk.media.widget.VideoView
android:id="#+id/videoViewRelative"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
</FrameLayout>
</LinearLayout>
You can do only create one state using XML. Switching has to be done in code.
First of all dump the fill_parent as it is deprecated. Then if you want to scale it dynamically, let it match the parent or set the smaller size in XML.
Then do the animation transition using view animation. Just as the parent's width and height and scale accordingly using either scale (mind setting the pivot to 0,0) or using size. I would use scaling with computed scale from 626/parentWidth.
But using dips fixes to only one display size/density

YouTube player in ScrollView android

When youtube player fragment nested in ScrollView I get error when rotate device to landscape:
YouTubePlayer.ErrorReason.UNAUTHORIZED_OVERLAY
And what is more interesting, is that the problem disappears when I remove ScrollView! But I can
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
/>
<fragment
android:name="com.google.android.youtube.player.YouTubePlayerFragment"
android:id="#+id/youtubeplayerfragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
YouTubePlayer.ErrorReason.UNAUTHORIZED_OVERLAY error indicates that *Playback has been stopped due to a view overlaying the player. This means that the YouTube Player has been obscured by some other view on top of it. The YouTube API can detect it and stop the Playback.
One very common reason for this to happen is when the fragment for holding the YouTube player is embedded in a scroll view. Scroll View adds additional layer of elements can be be scrolled. For.eg the in your case. The player contained in the same declaration would detect the overlap and would eventually stop giving the above error.
I have the same problem with a YoutubePlayer inside of a ScrollView and it stops with this message:
W/YouTubeAndroidPlayerAPI: YouTube video playback stopped due to unauthorized overlay on top of player. The YouTubePlayerView is not contained inside its ancestor android.widget.ScrollView{69b88e5 VFED.V... ........ 0,0-1794,1017 #7f0d0070 app:id/scrollview}. The distances between the ancestor's edges and that of the YouTubePlayerView is: left: 21, top: 196, right: 21, bottom: -164 (these should all be positive).
This happens all the time when the video is not fully visible on the screen. When it is visible completely, rotating the device works fine. To me this looks like a bug in the Youtube Android Player. I made a workaround with the following code:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// This is an ugly workaround to prevent youtube from (wrongly) thinking we have an
// overlay above the video. Having overlays is not allowed and the video would stop otherwise.
DisplayMetrics metrics = getResources().getDisplayMetrics();
int offset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, metrics);
scrollView.scrollTo(0, youtubePlayer.getView().getTop() - offset);
}
This obviously is not a good fix, because it depends on the ratio of the video and how it is shown on your display. Also your ScrollView will be scrolled to a different place after rotation (which you could re-reset manually later on).

CWAC-CAMERA position preview on top of available preview area when useFullBleedPreview = false

I'm trying to use CameraFragment from cwac-v9-camera to create custom Camera fragment taking and previewing Square images.
I want Preview and taken Picture to be completelly identical, so:
1. I useFullBleedPreview = false
2. I want preview picture to take full width and need to place my preview picture in the very top of the preview area, so I can cover rest of image with some view, to make it square.
The problem is that CameraView draws image in the center of camera preview area, and adds white lines on the top and buttom.
Is there any way to control where lobrary draws the preview picture?
I have the same issue and spent a day on this CWAC library (by the way, it is absolutely great). I would like to share my research and hopefully you (and me) would get a working solution soon.
Test Platform: Sony Xperia Z, Android 4.2.2
Test Resolution: 1080x1920.
Available Preview: 1280x720, 960x720, 720x480, 704x576, 640x480, 480x320, 320x240, 176x144.
Target Preview size: 1080x1080, a square, of course :D
Test done inside CameraHost.getPreviewSize() of my custom CameraHost.
If I provide a square view/size to the super class function here, I got 704x576. It is 11:9 (or 1.22222~) which is closest to 1:1 or 1.0. However, it looks blurry when enlarge to 1080 width and also distorted.
1280x720 is 16:9 (1.777~). The device camera got this by cropping the top and bottom (please note that camera is talking in landscape mode).
960x720 is 4:3 (1.333~). This is the full resolution of the device camera. It is my target resolution, where I only want the 720x720 inside 960x720 towards the top edge(portrait) or left edge(landscape).
In your custom CameraHost (extends SimpleCameraHost), limit the preview size:
#Override
public Size getPreviewSize(int orientation, int w, int h, Parameters p) {
Size size = super.getPreviewSize(orientation, 720, 960, p);
ViewGroup.LayoutParams params = cameraView.getLayoutParams();
params.width = 1080;
params.height = 960 * 1080/720;
cameraView.setLayoutParams(params);
return size;
}
layout.xml:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.commonsware.cwac.camera.CameraView
android:id="#+id/cameraView"
android:layout_width="match_parent"
android:layout_gravity="top|center_horizontal"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.android.widget.SquareView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:background="#99e0e0e0">
(your elements to cover up the extra area)
</LinearLayout>
</LinearLayout>
</FrameLayout>
Following is the result and comparing with the system camera, using 4:3.
Note:
I suppose you know how to create your own SquareView so I won't post the code of it here. You can read more here: Simple way to do dynamic but square layout
The piece of code in #4 is just test code - you need to figure out how it can be adapt for all devices.
Do NOT accept click event by the CameraView for focusing. Use the SquareView instead.
Is there any way to control where lobrary draws the preview picture?
It draws the image where the CameraView is. Where precisely within that space it resides depends upon the aspect ratio of the CameraView and the aspect ratio of the preview image and cannot be determined ahead of time.

Putting a button or text on an exact place of a scrollable background image

Say I have a background image as such.
http://i.imgur.com/rRCtzyl.png
I want to put a button or text right inside the white box. My text or button must scale and fit the box perfectly when the image is scaled according to device screen size. The image does not fit the screen vertically so it is scrollable. I know that I need to put them in a group if I want them both to scroll together.
But how do I place the button inside the box? Since its scrollable I dont know the exact x and y values of the box. Not to mention these values will change according to device screen size. And how do I make the buttons scale to fit the box with all screen sizes?
This image is only an example. Of course I wouldn't have a problem if I drew the box myself programmatically. I would know where to put the button. Assume I dont know the coordinates and the size of the box since I didn't d
If your box object is called box, set the button to the box.x and box.y like this:
object1.x = box.x
object1.y = box.y
The scroll aspect should not matter if you put the button and image in same group and scroll the group. Then all you need to do is position the button relative to the image once, the rest will be taken care of by corona.
What will matter is the screen resolution. One way of tackling this is to view the image at full resolution and compute at what x and y pixels the box is located. For instance,
image: 200 x 300 pixels
box top left: 100, 100 (pixels from top left of image)
box width height: 20, 60
Then you use ratios: top left of button box is at 0.5, 0.3333 of image size; the button box width is 0.1 and height 0.2 of image size. Then when you start app, you compute what will be the image scaling factor based on actual resolution and you apply that to box coordinates:
device 300 x 400:
image will be scaled 1.5x in width, 1.333x in height
so button box should be at (200*1.5*0.5, 300*1.333*0.333)
with width 20*1.5 and height 60*1.333

Categories

Resources