0

I use a Frame Layout, on which i bind my video player like this:

private void initVideoPlayer(View root) {
    mVideoPlayer = new TextureViewVideoPlayer(width, height);
    mVideoPlayer.setOnErrorListener(this);
    mVideoPlayer.setOnPreparedListener(this);
    mVideoPlayer.setOnCompletionListener(this);
    mVideoPlayer.setOnBufferingUpdateListener(this);
    mVideoPlayer.setOnSeekCompleteListener(this);
    mVideoPlayer.setOnVideoSizeChangedListener(this);
    mVideoPlayer.bindView((FrameLayout) root.findViewById(R.id.videoFrame), 0);
}

This is the onVideoSizeChanged function, from the TextureViewVideoPlayer:

@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    Log.i(TAG, "onVideoSizeChanged " + width + " ZZ " + height + " Display Height: " + displayheight + " --- REAL VIDEO RATIO: -- " + ((double) width / (double) height));
    if (this.mOnVideoSizeChangedListener != null)
        this.mOnVideoSizeChangedListener.onVideoSizeChanged(this, width, height);
    if (width == 0 || height == 0) {
        mp.release();
        Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
        return;
    }
    double ratio = ((double) width / (double) height);
    if (displayheight > height) {
        ratio = ((double) displayheight / (double) height);
    } else {
        ratio = ((double) height / (double) displayheight);
    }
    LayoutParams params = new FrameLayout.LayoutParams((int) (width * ratio), (int) (height * ratio));
    // LayoutParams params = new FrameLayout.LayoutParams((width),
    // (height));
    Log.i(TAG, "onVideoSizeChanged mod" + params.width + " ZZ " + params.height + " RATIO: " + ratio + " --- REAL RATIO: -- " + ((double) params.width / (double) params.height));
    params.gravity = Gravity.CENTER;
    mTextureView.setLayoutParams(params);
    this.mTextureView.requestLayout();
}

As you can see, it takes the video width and height of the video, it calculates the ratio, then it takes the displays height, and makes a ratio to see how much bigger (or smaller) the video is than the screen, then it creates the params for the video, with that ratio, and sets this parameters on the textureView.

In the xml, the VideoFrame i bind my player too has this:

<FrameLayout
    android:id="@+id/videoFrame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" >
</FrameLayout>

Now, if I keep it like this, the video is stretched, and even though it looks like its a rectangle, a part from the top and bottom of the video disappear (being 1:1 the width and height are the same, and the height is bigger that the screen). Now, if I don't use the ratio, and create the parameters with the width and height of the video (640 x 480) It will be a small square. (ratio 1:1), and stretched. Any ideea how this could be avoided?

PS: My texture view in fact is a Square Texture View, which had this onMeasure function:

 @Override
protected void onMeasure(int paramInt1, int paramInt2) {
    int i = View.MeasureSpec.getSize(paramInt1);
    setMeasuredDimension(i, i);
}

I've changed it into:

  @Override
protected void onMeasure(int paramInt1, int paramInt2) {
    int i = View.MeasureSpec.getSize(paramInt1);
    int j = View.MeasureSpec.getSize(paramInt2);
    setMeasuredDimension(i, j);
}

Hopefully, this fixes my issues.

rosu alin
  • 5,674
  • 11
  • 69
  • 150
  • 1
    It is probably because you calculate the ratio based only on the height, you should have a ratio2 variable to calculate the width too, but separately from the calculation of the ratio of the height (in a separate `if` and outside the current one). – g00dy Aug 07 '13 at 07:52
  • You'll have to recalculate the height AND width ratio, based on the screen, because sometimes, the height can be bigger than the screen, but not the width or the reverse. You'll have to maintain the ratio between the two ratios too. – g00dy Aug 07 '13 at 07:56
  • ok, but If i do not resize, I let it be the videos width and height (it's 640x480), it will still be squared, and not 4:3. And this using the original video size. Also did a logcat to the width and height after resize and its 1440 x 1080 (4:3) for htc one (which is full hd) – rosu alin Aug 07 '13 at 07:59
  • Well, if you have a display of 1920x1080, then the calculated ration will be 3, in this case (resolution 1440x1080), the ration is 2.25, which is strange, since you are doing this programmatically. I think that you should first remove the `android:layout_width`, `android:layout_height` and `android:fitsSystemWindows` from the layout, in order for them not to obscure the calculation. Do you have any other idea where this ratio of 2.25 might be comming from? – g00dy Aug 07 '13 at 08:11
  • that is not the screen ratio, is the ratio to resize the video. If the height of the video is 480, and the height of the screen is 1080, then we must multiply the video with 2.25 to get 1080. Now I find another thing, will edit the post – rosu alin Aug 07 '13 at 08:37
  • Yes, but 640x480 is 4:3 and 1920x1080 is 16:9. 2.25 is for the height ok, but for the width it should be 3. – g00dy Aug 07 '13 at 08:43
  • I said 1440x1080 (4:3) the display is 1920x1080 on htc one (but the video does not fill the display). Anyway, thanks for the help, the last thing might have fixed it. – rosu alin Aug 07 '13 at 08:44
  • Yeah, leave note here if it fixed it. If so, then paste it as an answer. – g00dy Aug 07 '13 at 08:45
  • globally, where the TextureView was declare, it was declareas a TextureView, but then it was initialized with SquareTextureView (which extends TextureView) Not being the one who did this class (my bosS), I did not know this, he showed my that class, and I instantly figured out what the issue was – rosu alin Aug 07 '13 at 08:46

1 Answers1

0

MY texture view had this:

 @Override
protected void onMeasure(int paramInt1, int paramInt2) {
int i = View.MeasureSpec.getSize(paramInt1);
setMeasuredDimension(i, i);

}

To fix it, I've changed it into:

@Override
protected void onMeasure(int paramInt1, int paramInt2) {
int i = View.MeasureSpec.getSize(paramInt1);
int j = View.MeasureSpec.getSize(paramInt2);
setMeasuredDimension(i, j);

}

rosu alin
  • 5,674
  • 11
  • 69
  • 150