Android SurfaceView 播放视频实现教程

2 下载量 111 浏览量 更新于2024-08-30 收藏 46KB PDF 举报
"使用Android SurfaceView实现视频播放功能的代码示例" 在Android开发中,SurfaceView是一个重要的组件,常用于处理高性能的图形或者视频播放,因为它提供了直接在硬件渲染图层上绘制的能力,减少了对主线程的影响。本文将探讨如何使用SurfaceView来实现在Android应用中播放视频。 首先,我们需要在布局XML文件中添加SurfaceView元素。在提供的描述中,我们可以看到一个相对布局(RelativeLayout)包含了一个SurfaceView和一些辅助视图,如TextView(显示当前时间)和SeekBar(进度条)。以下是一个简化版的XML布局示例: ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/sv" android:layout_width="match_parent" android:layout_height="250dp" /> <TextView android:id="@+id/te_nowTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/sv" android:layout_marginLeft="60dp" android:layout_marginBottom="10dp" android:textColor="#fff" android:text="00:00" /> <SeekBar android:id="@+id/sb" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_alignBottom="@id/sv" android:layout_centerHorizontal="true" /> </RelativeLayout> ``` 接下来,我们需要创建自定义的SurfaceView子类,例如`MySurfaceView`,并重写其中的关键方法。这个子类通常会包含一个`MediaPlayer`对象来处理视频播放。以下是一个简单的`MySurfaceView`类实现: ```java public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private MediaPlayer mediaPlayer; public MySurfaceView(Context context) { super(context); init(); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { holder = getHolder(); holder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { // 初始化MediaPlayer mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource("video_path"); mediaPlayer.prepare(); mediaPlayer.setDisplay(holder); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 当Surface大小改变时,可能需要调整MediaPlayer } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 释放资源 if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } public void startVideo() { if (mediaPlayer != null && !mediaPlayer.isPlaying()) { mediaPlayer.start(); } } public void pauseVideo() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); } } } ``` 在这个类中,我们创建了一个`MediaPlayer`实例,并在`surfaceCreated`方法中设置了视频数据源、准备视频并将其显示到Surface上。`surfaceChanged`和`surfaceDestroyed`方法则用于处理Surface的生命周期事件,如大小改变和释放资源。 最后,在Activity中,我们需要设置SurfaceView的监听器,以便更新进度条和显示当前时间。这可以通过以下方式实现: ```java public class MainActivity extends AppCompatActivity { private MySurfaceView mySurfaceView; private TextView currentTimeTextView; private SeekBar seekBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mySurfaceView = findViewById(R.id.sv); currentTimeTextView = findViewById(R.id.te_nowTime); seekBar = findViewById(R.id.sb); mySurfaceView.setMediaController(new MediaController(this)); mySurfaceView.setVideoPath("video_path"); mySurfaceView.setOnPreparedListener(mp -> { mp.start(); seekBar.setMax(mp.getDuration()); updateSeekBar(); }); mySurfaceView.setOnSeekCompleteListener(mp -> { mySurfaceView.seekTo(seekBar.getProgress()); mp.start(); }); } private void updateSeekBar() { final Handler handler = new Handler(); handler.postDelayed(() -> { int currentPosition = mySurfaceView.getCurrentPosition(); currentTimeTextView.setText(formatTime(currentPosition)); seekBar.setProgress(currentPosition); updateSeekBar(); }, 1000); } private String formatTime(int millis) { int totalSeconds = (int) (millis / 1000); int seconds = totalSeconds % 60; int minutes = (totalSeconds / 60) % 60; return String.format("%02d:%02d", minutes, seconds); } } ``` 这里,我们设置了SurfaceView的媒体控制器,并在视频准备就绪时开始播放。同时,我们通过`OnPreparedListener`和`OnSeekCompleteListener`监听视频状态,以便实时更新进度条和当前时间的显示。`updateSeekBar`方法定期更新进度条,而`formatTime`方法将毫秒转换为分钟:秒的格式。 总结,Android SurfaceView通过结合`MediaPlayer`对象,可以有效地实现视频播放功能。在实际应用中,你可能还需要考虑其他细节,如错误处理、播放控制、全屏切换等,以提供更加完善的用户体验。