我正在尝试播放.mp4格式的视频中的视频并录制视频相机应用。当我尝试做setDisplay时,我得到一个表面已经发布错误。我已经阅读了大多数论坛,我确信这是我处理SurfaceView或我的持有人的方式。在我打电话开始之前,我的表面总是被摧毁,我不知道如何保持它的创建。需要社区建议,因为这是我第一次使用此
我知道它正确地获取了文件的路径,当我删除任何播放视频的尝试时,音频部分工作。也许这与我在启动应用程序时在主屏幕上看到表面的事实有关,所以我的XML可能不正确但我认为应该没问题:
public class MainActivity extends Activity implements OnClickListener,
OnPreparedListener, OnCompletionListener, SurfaceHolder.Callback,
OnBufferingUpdateListener, OnVideoSizeChangedListener {
private static final int SELECT_VIDEO = 1;
private static final String TAG = "MainActivity";
private byte[] videoFile;
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private Bundle extras;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
private boolean hasActiveHolder = false;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPreview = (SurfaceView) findViewById(R.id.surface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
extras = getIntent().getExtras();
setupButtonClickListeners();
}
private void setupButtonClickListeners() {
Button exitButton = (Button) findViewById(R.id.exitButton);
exitButton.setOnClickListener(this);
Button selectVideoButton = (Button) findViewById(R.id.selectVideo);
selectVideoButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.exitButton:
this.finish();
break;
case R.id.selectVideo:
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Video"), SELECT_VIDEO);
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case SELECT_VIDEO:
doCleanUp();
Uri videoUri = data.getData();
String path = getPath(videoUri);
boolean success = readFromFile(path);
if (success) {
// Create a new media player and set the listeners
playVideo(path);
} else {
//do nothing for now
}
Log.i(TAG, path);
break;
}
}
}
private void playVideo(String path) {
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
// Here is the problem
synchronized (this) {
while (!hasActiveHolder) {
try {
this.wait();
} catch (InterruptedException e) {
//Print something
}
}
}
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private boolean readFromFile(String path) {
File file = new File(path);
try {
FileInputStream fis = new FileInputStream(file);
Log.i(TAG, "File Size: " + file.length());
videoFile = new byte[(int) file.length()];
fis.read(videoFile);
fis.close();
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
return true;
}
@SuppressWarnings("deprecation")
private String getPath(Uri uri) {
String[] projection = { MediaStore.Video.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndex(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "onCompletion called");
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.d(TAG, "surfaceChanged called");
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.d(TAG, "surfaceCreated called");
synchronized (this) {
hasActiveHolder = true;
this.notifyAll();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.d(TAG, "surfaceDestroyed called");
synchronized (this) {
hasActiveHolder = false;
this.notifyAll();
}
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
@Override
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
@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;
}
}
}
表面的我的XML如下所示。再一次,不确定为什么表面会在应用程序加载时出现,但我只是希望视频在从库中选择后播放。 :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<android.view.SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:id="@+id/changeFilePath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="78dp"
android:text="@string/changeFilePath" />
<Button
android:id="@+id/recordVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/changeFilePath"
android:layout_centerHorizontal="true"
android:text="@string/recordVideo" />
<Button
android:id="@+id/exitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordVideo"
android:layout_centerHorizontal="true"
android:layout_marginTop="49dp"
android:text="@string/exitButton" />
<Button
android:id="@+id/selectVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/recordVideo"
android:layout_centerHorizontal="true"
android:text="@string/selectVideo" />
</RelativeLayout>