我正在嘗試使用SurfaceView
從Android播放視頻。MediaPlayer播放聲音但不是視頻
我可以加載視頻,聲音播放正確但我看不到視頻。
這裏是我的活動:
public class VideoTest extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, OnErrorListener {
private static final String TAG = "MediaPlayerDemo";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String path;
private Bundle extras;
public static final String MEDIA = "media";
private static final int LOCAL_AUDIO = 1;
public static final int STREAM_AUDIO = 2;
private static final int RESOURCES_AUDIO = 3;
private static final int LOCAL_VIDEO = 4;
public static final int STREAM_VIDEO = 5;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
private RelativeLayout layout;
/**
*
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mPreview = new SurfaceView(this);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
extras = getIntent().getExtras();
mPreview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
layout = new RelativeLayout(this);
layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
layout.addView(mPreview, 0);
setContentView(layout);
}
private void playVideo(Integer Media) {
doCleanUp();
try {
mMediaPlayer = MediaPlayer.create(this, R.raw.video);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent + " pos : " + mMediaPlayer.getCurrentPosition() + "/" + mMediaPlayer.getDuration());
if (mMediaPlayer.isPlaying()) {
Log.d(TAG, "Playing");
} else {
mMediaPlayer.start();
}
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e(TAG, "invalid video width(" + width + ") or height(" + height
+ ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d(TAG, "surfaceChanged called. Width : " + j + ", height : " + k);
holder = surfaceholder;
mMediaPlayer.setDisplay(holder);
mIsVideoSizeKnown = true;
mVideoWidth = j;
mVideoHeight = k;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated called");
playVideo(extras.getInt(MEDIA));
}
@Override
protected void onPause() {
super.onPause();
releaseMediaPlayer();
doCleanUp();
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback " + mVideoWidth + "x" + mVideoHeight);
int width = mPreview.getWidth();
int height = mPreview.getHeight();
float boxWidth = width;
float boxHeight = height;
float videoWidth = mMediaPlayer.getVideoWidth();
float videoHeight = mMediaPlayer.getVideoHeight();
Log.i(TAG, String.format("startVideoPlayback @ video %dx%d - box %dx%d", (int) videoWidth, (int) videoHeight, width, height));
float wr = boxWidth/videoWidth;
float hr = boxHeight/videoHeight;
float ar = videoWidth/videoHeight;
if (wr > hr) {
width = (int) (boxHeight * ar);
} else {
height = (int) (boxWidth/ar);
}
Log.i(TAG, String.format("Scaled to %dx%d", width, height));
holder.setFixedSize(width, height);
mMediaPlayer.start();
}
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
Log.e(TAG, "ERROR called : " + arg1 + ", " + arg2);
return false;
}
}
的onVideoSizeChanged
功能是從來沒有所謂,但onPrepared
和surfaceChanged
被調用。 因此調用startVideoPlayback
函數,但視頻寬度和高度爲0.
我的視頻正在播放,因爲我可以聽到聲音,但屏幕上沒有顯示任何內容。 我也嘗試給對象的setFixedSize
函數提供原始寬度和高度,但我仍然沒有顯示任何東西。
你能幫我嗎? 我使用的是Android 8
編輯
這裏是日誌的時候我打從資源的視頻,我有:
WARN info/warning (1, 35)
WARN info/warning (1, 44)
DEBUG Duration : 101248
DEBUG surfaceChanged called. Width : 480, height : 270
INFO Info (1,35)
INFO Info (1,44)
DEBUG onPrepared called
VERBOSE startVideoPlayback 480x270
INFO startVideoPlayback @ video 0x0 - box 480x270
INFO Scaled to 480x0
DEBUG surfaceDestroyed called
EDIT 2
我嘗試了另一個視頻,它的工作。
這裏是 「不工作」 視頻的規格:
- 集裝箱:MP4 - 的QuickTime
- 率:2 340 Kbps的
- 格式:H.264/MPEG-4-AVC
- 大小:1280 * 640
- 看點像素:未定義
- 圖片比例:2.000
- 編碼配置文件:[email protected]
這裏是工作視頻規格:
- 容器:MP4 - QuickTime
- 費率:537 Kbps
- 格式:H.264/MPEG-4-AVC
- 尺寸:640 * 360
- 看點像素:未定義
- 圖片比例:16:9
- 編碼配置文件:[email protected]
你知道第一個視頻有什麼問題嗎?
logcat顯示錯誤? – Nfear
@Nfear我編輯我的問題添加日誌。我只有一些警告,但我不知道他們的意思 –
其實它與另一個視頻合作,我更新了我的問題。你知道爲什麼第一個視頻不工作(使用相同的編碼) –