Blu*_*ell 5 android media-player android-fragments android-videoview
我写了一个示例应用程序来重现问题:
https://github.com/blundell/VideoRatioProblemPerDevice
该VideoView文档状态:
显示视频文件....负责从视频计算其测量值,以便可以在任何布局管理器中使用,并提供各种显示选项,如缩放
问题是三星Galaxy S3对视频做了奇怪的事情而不尊重视频的比例.(也发生在HTC设备上).
全屏片段的活动:
我发现,当在三星Galaxy S3上播放视频时,它将以不正确的比例播放.看起来它已被拉伸到视图的高度而不考虑原始视频的比例.
这里:

但是,如果我在三星Galaxy Nexus上播放视频,则视频的比例正确.
这里:

如果我强制视频占据片段的全部大小,它在S3上看起来没问题(因为屏幕的比例是视频的比例).但是我不想这样做,因为它搞砸了在其他地方使用的片段,即平板电脑.
代码是:
带有VideoView片段的活动.可以在这里看到:GITHUB CODE LINK
如果你想要一些代码在这里是hte VideoPlayerFragment:
public class VideoPlayerFragment extends Fragment {
private static final String TAG = "VideoPlayer";
private FitVideoView videoView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_video_player, container, false);
videoView = (FitVideoView) root.findViewById(R.id.surface);
return root;
}
public void playVideo() {
Uri uri = Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.test_vid);
Log.d(TAG, "Uri is: " + uri);
setVideoLocation(uri);
if (!videoView.isPlaying()) {
videoView.start();
}
}
private void setVideoLocation(Uri uri) {
try {
videoView.setVideoURI(uri);
} catch (Exception e) {
Log.e(TAG, "VideoPlayer uri was invalid", e);
Toast.makeText(getActivity(), "Not found", Toast.LENGTH_SHORT).show();
}
}
public void pauseVideo() {
if (videoView.isPlaying()) {
videoView.pause();
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以这个问题VideoView与MediaPlayer+ 一起发生SurfaceView.
当系统询问视频的宽度x高度时,它返回640x480时应该返回852x480.
即
@Override
public void onPrepared(MediaPlayer mp) {
mp.getVideoWidth();
mp.getVideoHeight();
}
Run Code Online (Sandbox Code Playgroud)
这是MediaPlayer处理视频容器/编解码器时的错误或视频文件本身的问题.

无论哪种方式,我通过添加我知道视频的宽度和高度是我的代码来规避它.我用这个修复程序更新了Git Repo.黑客警报
您可以应用此修复程序的VideoView,或直接到MediaPlayer+ SurfaceView您的选择.这是VideoView答案:
public class FitVideoView extends VideoView {
private final int mVideoWidth = 853;
private final int mVideoHeight = 480;
private boolean applyFix = true;
public FitVideoView(Context context) {
super(context);
}
public FitVideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FitVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (applyFix) { // A Toggle so I can see both results
// This doesn't ask the video for it's size, but uses my hardcoded size
applyFix(widthMeasureSpec, heightMeasureSpec);
} else {
// This asks the video for its size (which gives an incorrect WxH) then does the same code as below
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private void applyFix(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
if (mVideoWidth > 0 && mVideoHeight > 0) {
if (mVideoWidth * height > width * mVideoHeight) {
Log.d("TAG", "image too tall, correcting");
height = width * mVideoHeight / mVideoWidth;
} else if (mVideoWidth * height < width * mVideoHeight) {
Log.d("TAG", "image too wide, correcting");
width = height * mVideoWidth / mVideoHeight;
} else {
Log.d("TAG", "aspect ratio is correct: " + width + "/" + height + "=" + mVideoWidth + "/" + mVideoHeight);
}
}
Log.d("TAG", "setting size: " + width + 'x' + height);
setMeasuredDimension(width, height);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6739 次 |
| 最近记录: |