基于MediaPlayer实现视频播放

Android MediaPlayer播放视频详细步骤 MediaPlayer播放视频 阅读详情

一、概述

一个简单的视频播放器,满足一般的需求。使用原生的 MediaPlayer 和 TextureView来实现。

功能点:

  1. 获取视频的首帧进行展示,网络视频的首帧会缓存
  2. 视频播放,本地视频或者网络视频
  3. 感知生命周期,页面不可见自动暂停播放,页面关闭,自动释放
  4. 可以在RecyclerView的item中使用
  5. 网络视频可配置下载(如果网络视频地址可以下载),下次再播放时播放下载好的视频。

演示图:
在这里插入图片描述

二、使用

VideoPlayView videoPlayView = findViewById(R.id.videoPlayView);
getLifecycle().addObserver(videoPlayView);
//设置视频文件路径
videoPlayView.setFileDataSource(filePath);
//设置网络视频地址
//videoPlayView.setNetDataSource(netAddress);
int position = intent.getIntExtra("position", 0);
videoPlayView.setTargetPosition(position);

三、实现代码

主要涉及三个类:

  1. VideoPlayView 播放器
  2. VideoRepository 获取视频首帧,缓存视频首帧,判断网络视频是否有缓存等处理
  3. VideoDownload 网络视频下载

VideoPlayView

VideoPlayView布局
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/frameLayout"
    android:background="@color/black"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextureView
        android:id="@+id/textureView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />

    <ImageView
        android:id="@+id/previewIv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@null" />

    <ProgressBar
        android:id="@+id/loadProgressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_gravity="center" />

    <FrameLayout
        android:id="@+id/mediaControllerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/ivPlay"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_gravity="center"
            android:contentDescription="@null"
            android:src="@drawable/play" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_gravity="bottom"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tvTime"
                android:layout_width="60dp"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textColor="@color/white"
                android:text="00:00"
                tools:ignore="HardcodedText" />

            <androidx.appcompat.widget.AppCompatSeekBar
                android:id="@+id/seekBar"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_marginHorizontal="4dp"
                android:layout_weight="1" />

            <TextView
                android:id="@+id/tvDuration"
                android:layout_width="60dp"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textColor="@color/white"
                tools:text="2:40:10" />

            <ImageView
                android:id="@+id/ivScreen"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:contentDescription="@null"
                android:padding="5dp"
                android:src="@drawable/fullscreen" />

        </LinearLayout>
    </FrameLayout>

</FrameLayout>
VideoPlayView 代码
public class VideoPlayView extends FrameLayout implements LifecycleObserver,
        View.OnClickListener, SeekBar.OnSeekBarChangeListener, TextureView.SurfaceTextureListener,
        MediaPlayer.OnInfoListener, MediaPlayer.OnErrorListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnBufferingUpdateListener,
        MediaPlayer.OnVideoSizeChangedListener, VideoRepository.VideoFrameCallback {
   
   

    private final int DURATION_REFRESH_PROGRESS = 1000;//播放进度更新间隔
    private final int DURATION_CLOSE_CONTROLLER = 6000;//控制视图显示时长
    private final int CLOSE_CONTROLLER = 122;//关闭控制视图消息
    private final int REFRESH_PROGRESS = 133;//刷新播放进度

    @Nullable
    private MediaPlayer mediaPlayer;

    private final VideoRepository videoRepository;

    public final TextureView textureView;
    public final ImageView ivPreview;
    public final ImageView ivPlay;
    public final AppCompatSeekBar seekBar;
    public final FrameLayout mediaControllerView;
    public final ProgressBar loadProgressBar;
    public final TextView currentTimeTv;
    public final TextView durationTimeTv;
    public final ImageView ivScreen;

    private int mWidth;
    private int mHeight;
    private int screenOrientation;

    private boolean isMediaAutoPausing = false;//是否是自动暂停的(页面在后台时自动暂停,回到前台时自动播放),手动暂停的不算
    private boolean isPause = false;//页面是否pause
    private int duration;//视频总长度
    private int pausePosition;//暂停时的播放进度
    private int targetPosition;//目标播放进度,从这个进度开始播放
    //目标播放比例,还没prepare之前,不知道视频的总长度。用户拖动了进度条,记住这个比例,等prepare之后根据比例计算出进度
    private float targetRatio;
    private boolean hadSetDataSource = false;//是否设置了播放的资源
    private boolean hadPrepare = false;//是否prepare成功,只有调用过才能正常播放
    private String videoSource;//视频源,本地文件路径或者网络地址
    //是否是网络视频源
    private boolean isNetSource = false;
    //是否下载网络视频源
    private boolean needDownloadNetSource = false;

    public VideoPlayView(@NonNull Context context) {
   
   
        this(context, null);
    }

    public VideoPlayView(@NonNull Context context, @Nullable AttributeSet attrs) {
   
   
        this(context, attrs, 0);
    }

    public VideoPlayView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   
   
        super(context, attrs, defStyleAttr);
        inflate(context, R.layout.media_play_layout, this);
        textureView = findViewById(R.id.textureView);
        textureView.setSurfaceTextureListener(this);
        ivPreview = findViewById(R.id.previewIv);
        ivPlay = findViewById(R.id.ivPlay);
        seekBar = findViewById(R.id.seekBar);
        loadProgressBar = findViewById(R.id.loadProgressBar);
        currentTimeTv = findViewById(R.id.tvTime);
        durationTimeTv = findViewById(R.id.tvDuration);
        mediaControllerView = findViewById(R.id.mediaControllerView);
        ivScreen = findViewById(R.id.ivScreen);
        findViewById(R.id.frameLayout).setOnClickListener(this);
        seekBar.setOnSeekBarChangeListener(this);
        ivPlay.setOnClickListener(this);
        ivScreen.setOnClickListener(this);
        videoRepository = new VideoRepository();
        initMediaPlayer();
        screenOrientation = getResources().getConfiguration().orientation;
    }

    private void initMediaPlayer() {
   
   
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setScreenOnWhilePlaying(true);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnInfoListener(this);
        mediaPlayer.setOnErrorListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnSeekCompleteListener(this);
        mediaPlayer.setOnBufferingUpdateListener(this);
        mediaPlayer.setOnVideoSizeChangedListener(this);
    }

    /**
     * 给MediaPlayer设置播放源
     *
     * @param videoSource 视频源
     */
    private void realSetDataSource(String videoSource) {
   
   
        this.videoSource = videoSource;
        duration = 0;
        durationTimeTv.setText(null);
        hadPrepare = false;
        Uri mediaUri;
        if (isNetSource) {
   
   
            mediaUri = videoRepository.getMediaUri(getContext(), videoSource);
        } else {
   
   
            mediaUri = videoRepository.getLocalMediaUri(videoSource);
        }
        if (mediaUri 
在GSYVideoPlayer中实现VLC 内核 GSYVideoPlayer 是一个比较火的开源框架。其支持Android 系统中的MediaPlayer内核,ExoPlayer 内核, ijkPlayer 内核。 在我使用的过程中发现不支持h265格式的avi 文件播放,所以我实现了一个VLC内核。 import android.content.Context; import android.net.Uri; import android.os.Handler; import android.view.Surface; import android 阅读详情

相关推荐

MediaPlayer构建音乐播放器,你所需知道的一切

使用MediaPlayer构建一个基本的音乐播放器,你所需知道的一些细节与注意事项。

boybeak的专栏 3874

MediaPlayer播放音频与视频

9.2 MediaPlayer播放音频与视频 分类Android 基础入门教程 本节引言: 本节带来的是Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码 和播放音视频。它支持三种不同的媒体来源: 本地资源 内部的URI,比如你可以通过Content...

jinyu_mobao的博客 1117

android MediaPlayer 实现切换视频播放比例

在做项目的过程中遇到切换视频播放比例的

a22422931的博客 4099

使用MediaPlayer播放视频

MediaPlayer

qq_53077129的博客 573

MediaPlayer+TextureView实现视频播放

Android实现视频播放器的途径有两种: 使用VideoView 通过MediaPlayer + SurfaceView/ TextureView 1. VideoView VideoView使用比较简单,配合MediaController可以达到控制播放、暂停、快进、快退、切换视频、进度条显示等,具体使用在这里不在赘述了。 2. MediaPlayer + SurfaceView / T...

Han_Jang的博客 1374

Android 通过VideoView+MediaPlayer实现视频播放

现实视频播放有两种方法,第一种是利用了VideoView来实现的,第二种是MediaPlayer和SurfaceView实现。第一种方法 运行效果如下:在清单文件(AndroidManifest.xml)要加入读取内存卡的权限<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.

qq_37278353的博客 3468

【Sceneform-EQR】通过sceneform-eqr实现一个视频播放器(使用安卓MediaPlayer实现视频播放

在前一篇文档中介绍了如何在AR\三维场景创建几种背景,本文将侧重介绍如何使用安卓MediaPlayer实现视频播放

一个XR(AR|VR|MR)程序猿的博客(EQ-雪梨蛋花汤) 1976

MediaPlayer+SurfaceView实现视频播放

我这个人走得很慢,但是我从不后退。 之前给大家分享过使用MediaController类实现视频播放器,今天呢给大家分享可以自定义的视频播放器,那就是使用MediaPlayer+SurfaceView来实现。废话不多说,直接上代码。 目录1. 设计思路2. 设计布局3. 实现逻辑4. 权限获取5. Demo展示 1. 设计思路 使用 MediaPlayer+SurfaceView实现视频播放器的流程如图所示,在学习音视频播放器的时候,一个老师画的图,在此直接借用。 2. 设计布局 <?xml v.

小曾同学的博客 2380

Android开发中MediaPlayer与SurfaceView结合实现高效视频播放

Android平台的多媒体开发中,与是构建视频播放功能的核心组件。负责音视频的解码与播放控制,而则专注于高效的视频画面渲染。二者结合,能够实现流畅、低延迟的视频播放体验。本章将从基础概念入手,深入解析的工作流程与的绘制机制,帮助开发者理解其在Android图形系统中的角色与协同方式,为后续实战开发奠定扎实的理论基础。本章详细介绍了Android视频资源的三种主要加载方式:本地文件路径、应用资源文件(R.raw与assets)、网络流媒体URL。

weixin_35294091的博客 915

Android 安卓使用 MediaPlayer 实现视频播放列表

它接受一个视频列表作为参数,并将视频列表中的每个视频与对应的布局进行绑定。MediaPlayerAndroid 提供的一个用于音频和视频播放的类,它提供了一个简单而强大的接口,可以实现各种播放控制和功能。在布局文件中添加一个 RecyclerView,用于展示视频列表,以及一些控制按钮,如播放、暂停、上一个、下一个等。同时,我们为按钮设置了相应的点击事件监听,用于处理播放/暂停、切换上一个和下一个视频的逻辑。接着,在 Java 代码中,我们需要创建一个适配器类,用于将视频列表数据和布局进行绑定。

ByteGlide的博客 1204

SurfaceView+MediaPlayer实现视频播放

效果图,是动画片《辛特尔》的截图,加载可能要几十秒 不要忘了网络权限 <uses-permission android:name="android.permission.INTERNET" /> MainActivity.java代码 public class MainActivity extends AppCompatActivity { private SurfaceView surfaceView; private Med

知道这个有什么用? 3137

纯QML使用MediaPlayer实现视频播放的几个问题

纯QML使用MediaPlayer实现视频播放的几个问题 一、在工程PRO文件中,添加:multimedia模块 QT += multimedia 二、Qt视频播放播放不了视频并报错: DirectShowPlayerService::doRender: Unresolved error code0x80040266 () QtMultimedia使用的是系统默认的音视频编/解码器,如果系统没有...

qq_44665944的博客 3944

Android视频播放实现的三种办法(MediaPlayer+SurfaceView,VideoView,Vitamio框架)

今天来说一下Android中怎么实现视频播放,我主要说三种:1.MediaPlayer+SurfaceView;2.VideoView;3.Vitamio框架。1.MediaPlayer+SurfaceView这种方法是基础,后面的两种方法其实就是把这种方法封装了一下,使用起来更方便些。我认为大家基本都...

whyqcwy的专栏 5803

Android SurfaceView+MediaPlayer实现视频播放

1.案例一 布局文件: xml version="1.0" encoding="utf-8"?> LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" and

xuan521521的博客 1046

SurfaceView+MediaPlayer视频播放并用SharedPreferences实现暂停功能

SurfaceView+MediaPlayer+SharedPreferences制作视频播放Demo

CTJ_CSDN的博客 1712

android 使用MediaPlayer实现视频播放

android 使用MediaPlayer 和SurfaceView实现视频播放

lebsharing的专栏 960

mediaplayer+surfaceview实现视频播放以及全屏窗口切换

mediaplayer+surfaceview实现视频暂停播放、动态设置视频横竖屏全屏半屏

_淡然_花落_的专栏 5650

Android MediaPlayer+SurfaceView+自定义控制器实现视频播放

VideoView继承了SurfaceView同时实现MediaPlayerControl接口,MediaController则是安卓封装的辅助控制器,带有暂停,播放,停止,进度条等控件。本demo基于Android11开发,实现了简单的视频播放功能,可以拖动进度条,快进/快退和播放上一个视频/播放下一个视频,同时通过悬浮窗的形式查看视频详情。5、将展示视频详情的布局及组件初始化,创建WindowManager对象并设置窗口对应的值,将设置好的值和布局添加进WindowManager对象。

qnako的博客 4511
上一篇: ProgressBar圆形进度
ganduwei
博客等级 码龄12年 30粉丝 41原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值