使用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);
        }
    }
}

总结

针对不同情况选择适合的视频播放器插入方法,但是如果可以像平常使用腾讯、爱奇艺在视频播放角落处设置一个全屏按钮,不用进行页面跳转的话会更好。具体实现还在学习中。


本文由转载于互联网,如有侵权请联系删除!