使用Android制作视屏播放器
目录
前言
Android小作业,含实现本地视频播放界面,实现全屏播放视频界面,两个界面所采用的的控件不同,可进行比较学习,作为大作业参考代码。
一、展示预览
第一界面:主要使用VideoView、button、mediaConrtroller类
第二界面:SurfaceView控件和MediaPlayer共同放视频
将这两个界面进行跳转只需要在跳转的button中设置intent事件即可(具体代码看两个java文件中intent部分)
二、详细步骤 1.准备工作
准备一张背景图,作为界面1背景,命名为bg;准备一个.mp4格式的视频light。如果是其他格式,可以通过【格式工厂】进行格式转换,若无,点击前往下载……
文件界面如图:
2、主界面设计
确定布局为约束布局,为了方便控制视频的开始与结束,设置两个button来控制播放和暂停,id为start和pause; 通过VideoView将视频导入,id为videoView;
主界面布局代码如下:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@drawable/bg">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="250dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.239"
tools:layout_editor_absoluteX="0dp" />
<Button
android:id="@+id/start"
android:layout_width="204dp"
android:layout_height="71dp"
android:text="播放"
android:backgroundTint="@color/black"
android:textColor="@color/white"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<Button
android:id="@+id/pause"
android:layout_width="204dp"
android:layout_height="68dp"
android:backgroundTint="@color/black"
android:textColor="@color/white"
android:text="暂停"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.004" />
<Button
android:id="@+id/all"
android:layout_width="match_parent"
android:layout_height="71dp"
android:backgroundTint="@color/black"
android:text="点击全屏播放>>"
android:textColor="@color/white"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.586" />
androidx.constraintlayout.widget.ConstraintLayout>
3、主界面java文件
要想让视频播放,需要在java文件设置对应的方法。需要修改对应的id以及包名、文件名。
代码如下:
package com.example.miao1115;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
VideoView videoview;
Button start;
Button pause;
MediaController mediaController;
Button all;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoview=findViewById(R.id.videoView);
all=findViewById(R.id.all);
mediaController= new MediaController(this);
initview();
//跳转全屏界面
all.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent backmain = new Intent(MainActivity.this, MainActivity2.class);
startActivity(backmain);
finish();
}
});
}
private void initview(){
start=findViewById(R.id.start);
pause=findViewById(R.id.pause);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
init();
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
videoview.stopPlayback();
}
});
}
private void init(){
//启动视频播放的方法
String uri="android.resource://"+getPackageName()+"/"+R.raw.light;
videoview.setVideoURI(Uri.parse(uri));
videoview.setMediaController(mediaController);
mediaController.setMediaPlayer(videoview);
videoview.requestFocus();//设置视频控制组件传入videoview对象
videoview.start();//设置开始播放
}
}
4、全屏界面设计
主要应用的是SurfaceView控件和MediaPlayer共同放视频,可以大大减少内存,避免视频卡顿。
使用SurfaceView好处:
全屏播放界面只需要设置一个返回按钮回到主界面即可,代码如下:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2"
android:id="@+id/cl"
android:background="@color/black">
<SurfaceView
android:id="@+id/sv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<SeekBar
android:id="@+id/sbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.977" />
<ImageView
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="click"
android:src="@android:drawable/ic_media_pause"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/back"
android:layout_width="143dp"
android:layout_height="70dp"
android:backgroundTint="@color/black"
android:text="返回"
android:textColor="@color/white"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
androidx.constraintlayout.widget.ConstraintLayout>
5、全屏布局
注意:在默认情况下全屏是竖屏,显然这不是我们想要的结果。
有两种方法进行调整,第一种方法是在AndroidManifest文件中加入以下语句:
android:screenOrientation="landscape"
但是加过去后,我发现因为这是全局配置文件,会影响主界面也变成横屏,所以如果不是想要所有界面都采用横屏应该采用第二种方法。
第二种办法是在Java文件中设置全屏,为了更为稳定,常常需要一个if语句来对原本是否横屏进行判断,如果不是横屏,就进行横屏设置。加入代码如下:
if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
全屏界面Java完整代码如下:
package com.example.miao1115;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Toast;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity2 extends AppCompatActivity implements SurfaceHolder.Callback, SeekBar.OnSeekBarChangeListener {
private SurfaceView sv;
private SurfaceHolder holder;
private MediaPlayer mediaplayer;
private ConstraintLayout cl;
private Timer timer;
private TimerTask task;
private SeekBar sbar;
private ImageView play;
private Button back;
@Override
protected void onCreate(Bundle savedInstanceState) {
if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
sv = (SurfaceView) findViewById(R.id.sv);
// 得到SurfaceView的容器,界面内容是显示在容器里面的
cl = (ConstraintLayout) findViewById(R.id.cl);
play = (ImageView) findViewById(R.id.play);
sbar = (SeekBar) findViewById(R.id.sbar);
back = findViewById(R.id.back);
sbar.setOnSeekBarChangeListener(this);
holder = sv.getHolder();
// 过时的APT,如果4.0以上的系统不写没问题,否则必须要写
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(this);
// 初始化计时器
timer = new Timer();
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent backmain = new Intent(MainActivity2.this, MainActivity.class);
startActivity(backmain);
finish();
}
});
task = new TimerTask()
{
@Override
public void run()
{
if (mediaplayer != null && mediaplayer.isPlaying())
{
int total = mediaplayer.getDuration();
sbar.setMax(total);
int progress = mediaplayer.getCurrentPosition();
sbar.setProgress(progress);
}
else{
play.setImageResource(android.R.drawable.ic_media_play);
}
}
};
// 设置TimerTask延迟500ms,每隔500ms执行一次
timer.schedule(task, 500, 500);
}
//播放暂停按钮的点击事件
public void click(View view)
{
if (mediaplayer != null && mediaplayer.isPlaying())
{
mediaplayer.pause();
play.setImageResource(android.R.drawable.ic_media_play);
} else
{
mediaplayer.start();
play.setImageResource(android.R.drawable.ic_media_pause);
}
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder)
{
try {
mediaplayer = new MediaPlayer();
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+"://"+
getPackageName()+"/"+R.raw.light);
try {
mediaplayer.setDataSource(MainActivity2.this,uri);
} catch (IOException e) {
Toast.makeText(MainActivity2.this,"播放失败",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
mediaplayer.setDisplay(holder);
mediaplayer.prepareAsync();
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
@Override
public void onPrepared(MediaPlayer mp) {
mediaplayer.start();
}
});
} catch (Exception e) {
Toast.makeText(MainActivity2.this, "播放失败",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { }
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(mediaplayer. isPlaying()){
mediaplayer.stop(); } }
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) { }
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
int position = seekBar.getProgress();
if (mediaplayer != null)
{
mediaplayer.seekTo(position);
}
}
}
总结
针对不同情况选择适合的视频播放器插入方法,但是如果可以像平常使用腾讯、爱奇艺在视频播放角落处设置一个全屏按钮,不用进行页面跳转的话会更好。具体实现还在学习中。