安卓实现M3U8文件的下载和播放

这篇具有很好参考价值的文章主要介绍了安卓实现M3U8文件的下载和播放。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

现如今网络上的视频大多数都是m3u8格式的,使用m3u8格式有以下好处

1. 方便切换码率,例如从高清转到蓝光

2. 节约流量,m3u8实际切割成一段段的TS后缀视频,传统请求是把整个文件流返回去,网络不好或者文件过大时,都会造成响应缓慢,m3u8则是返回一个个的ts文件,当前ts缓存完才会自动请求下一个ts,ts切割的很小,所以,几乎是秒响应

3 防盗,m3u8可以对ts文件加密,其他就不知道

下面介绍如何下载m3u8

本次介绍一个下载框架,aria官方文档  1.1 开始 · Aria 使用指南 (laoyuyu.me)

需要在app.build引入aria

implementation 'me.laoyuyu.aria:core:3.8.16'
annotationProcessor 'me.laoyuyu.aria:compiler:3.8.16'
implementation 'me.laoyuyu.aria:m3u8:3.8.16'

引入完成后,可以使用以下代码下载文件,,如果是mp4或者图片,可以使用以下代码下载,下载代码:

Aria.download(this).register();//注册aria

long taskId = Aria.download(SingleTaskActivity.this)
        .load(url) // 下载地址
        .setFilePath(filePath) // 设置文件保存路径
        .create();

如果是m3u8,需要重写IBandWidthUrlConverter和IVodTsUrlConverter,先说说m3u8,我们打开一个m3u8,发现他是一个索引文件,记录下一个m3u8的码率,下一个m3u8则记录对应的ts文件,如下

安卓实现M3U8文件的下载和播放

安卓实现M3U8文件的下载和播放

 但是有这样3三种情况,

1. 记录的码率文件是全路径路径,如:https://xxx.com/xxx/index.m3u8

2. 记录的码率是相对路径,如 xxx/index.m3u8(上图就是这种情况)

3. 记录的码率只要文件名,如 index.m3u8

那么aria就不知根据那种规则下载,所以我们要重写IBandWidthUrlConverter,同理Ts文件也一样,也要重写IVodTsUrlConverter

重写IBandWidthUrlConverter:

public class M3U8_Converter implements IBandWidthUrlConverter {
   @Override
   public String convert(String m3u8Url, String bandWidthUrl) {
       System.out.println("m3u8Url:"+m3u8Url);
       System.out.println("bandWidthUrl:"+bandWidthUrl);
       //m3u8Url:第一个m3u8,连接到下一个m3u8
       //bandWidthUrl:第二个m3u8,包含不同码率的ts视频
       /*第二个m3u8有些文件带有全路径,如:http://xxxx.xxx.com/xxx
       *有些没有,如:/20210927/3oCoCiM4/hls/index.m3u8
       *因此需要区分,区分规则如下:
       * 如果包含有http或者https,一定是全路径,直接访问
       * 如果没有则是用域名+第二个文件路径,如:(域名)http://xxxx.xxx.com/20210927/3oCoCiM4/hls/index.m3u8(路径)
       */
       if(bandWidthUrl.contains("http://")||bandWidthUrl.contains("https://")){
           return bandWidthUrl;
       }else{
           //获取域名
       URL url = new URL(m3u8Url);
       String host=url.getProtocol()+"://"+url.getHost()+":"+url.getDefaultPort();
       return host+"/"+bandWidthUrl;
       }

   }

重写IVodTsUrlConverter

public List<String> convert(String m3u8Url, List<String> tsUrls) {
    System.out.println("m3u8Url:"+m3u8Url);
    System.out.println("tsUrls:"+tsUrls);
    //m3u8Url:m3u8文件,包含ts文件
    //tsUrls:所有的ts文件
    /*某些ts文件带有全路径,如:http://xxxx.xxx.com/xxx.ts
     *有些没有只有相对路径,如:/20210927/3oCoCiM4/hls/xx.ts
     * 有些只有文件名,如:xxx.ts
     *因此需要区分,区分规则如下:
     * 如果包含有http或者https,一定是全路径,直接访问
     * 如果只有相对则是用域名+ts文件路径,如:(域名)http://xxxx.xxx.com/20210927/3oCoCiM4/hls/0.ts(路径)
     * 如果只有文件名,则是1 截取0到xxx.m3u8(不包含)的路径 2加上ts文件名,如:
     * http://xxxx.xxx.com/20210927/3oCoCiM4/index.m3u8
     * 去掉路径中xxx.m3u8的路径
     * http://xxxx.xxx.com/20210927/3oCoCiM4/
     * 加上ts文件名
     */
    List<String> newTslist=new ArrayList<>();
    String pattern="[0-9a-zA-Z]+[.]ts";
    Pattern r = Pattern.compile(pattern);
    for (int i = 0; i < tsUrls.size(); i++) {
        String tspath=tsUrls.get(i);
        Matcher m = r.matcher(tspath);
        //全路径
        if(tspath.contains("http://")||tspath.contains("https://")){
            newTslist.add(tspath);
        }
        //只有文件名
        else
        if(m.find()){
            int e=m3u8Url.lastIndexOf("/")+1;
            newTslist.add(m3u8Url.substring(0,e)+tspath);
        }
        //相对路径
        else{
            String host=Host.gethost(m3u8Url);
            newTslist.add(host+"/"+tspath);
        }
    }

    return newTslist;
}

重写完这两个类,我们启动下载时,就会根据我们重写的规则进行访问

启动下载

Aria.download(this).register();//注册aria
M3U8VodOption option = new M3U8VodOption(); // 创建m3u8点播文件配
option.setUseDefConvert(false);//必须设置false,否则不会使用你重写那两个类
option.setBandWidthUrlConverter(new M3U8_Converter());
option.setVodTsUrlConvert(new TS_Converter());
option.generateIndexFile();
long taskId = Aria.download(Activity_Home.context)
        .load("m3u8的下载路径") 
        .setFilePath("保存路径", true) // 设置点播文件保存路径,true表示,如果当前目录有文件,则覆盖相同的文件
        .m3u8VodOption(option)   // 调整下载模式为m3u8点播
        .create();

接下来是几个注解

//任务开始时

@Download.onTaskStart void taskStart(DownloadTask task) {}

//任务运行时

@Download.onTaskRunning void running(DownloadTask task) {}

//任务停止时 

@Download.onTaskStop void taskStop(DownloadTask task) {}

//下载失败时

@Download.onTaskFail void taskFail(DownloadTask task) {}

//下载完成时

@Download.onTaskComplete void taskComplete(DownloadTask task) {}

//任务删除时

@Download.onTaskCancel void taskCancel(DownloadTask task) {}

其中DownloadTask有以下方法

DownloadTask.getPercent();  //下载进度
DownloadTask.getSpeed();//下载速度,原始数据,需要手动转为mb/s,kb/s
DownloadTask.getConvertFileSize();//文件大小,已处理单位,自动为xxmb或者xxgb
DownloadTask.getConvertCurrentProgress();//已下载的文件大小,单位已处理

具体用法可以参考官方文档

这样m3u8就下载好了,我们可以在@Download.onTaskRunning void running(DownloadTask task) {}中监听下载进度等,具体可以根据实际业务开发

接下来我们讲讲m3u8的播放,网络m3u8可以直接赋值给videoview,也可以正常播放,我们理所当然的认为下载到本地的m3u8也可以赋值给videoview,然后正确的播放,但是,事实上,我们把本地路径赋值给videoview,不能正确播放,会出现该视频无法播放,那么怎么解决呢,m3u8格式只支持网络播放,那么我们把本地路径换为本地网络路径就可以解决,如http://127.0.0.1:80/index.m3u8,需要本地搭建webservice,搭建步骤如下:

引入nanohttpd

implementation 'org.nanohttpd:nanohttpd:2.3.1'

然后继承实现NanoHTTPD

public class MyServer extends NanoHTTPD {
   public static String M3U8="application/x-mpegURL";
   public static String Video="video/mp4";
   public static String text="video/mp4";
    public static String TS="video/mp2t";
    public MyServer(int port) {
        super(port);
    }

    public MyServer(int port,Context context) {
        super(port);
    }
    public MyServer(String hostname, int port) {
        super(hostname, port);
    }

    @Override
    public Response serve(IHTTPSession session) {

        try {
            //文件下载得保存路径
            String path = "/storage/emulated/0/Android/data/com.example.iflq/files/Download/";
            //本地地址转为网络地址
            if (session.getUri().contains(path)) {
                File f = new File(session.getUri());
                FileInputStream inputStream = new FileInputStream(f);
                return newFixedLengthResponse(Response.Status.OK, M3U8, inputStream,f.length());

            }

            //默认页面
            String msg = "<html><body><h1>Hello server</h1></body></html>";
            return newFixedLengthResponse(msg);
        }catch (Exception e){
            e.printStackTrace();
            String msg = "<html><body><h1>服务器出错</h1></body></html>";
            return newFixedLengthResponse(msg);
        }
    }
}

启动webservice

MyServer mMyServer = new MyServer(8080);
try {
    mMyServer.start();
} catch (IOException e) {
    e.printStackTrace();
}

这时候我们就可以把m3u8赋值给videoview了,videoView.setVideoPath("http://127.0.0.1:8080/index.m3u8");

注意文件路径(必须存在,否则一样不能播放),注意文件的返回格式(application/x-mpegURL)

效果:

安卓实现M3U8文件的下载和播放

如果我说的不够明白,欢迎提问,如果有错漏,欢迎指出

来都来了,留个评论呗,点个赞呗文章来源地址https://www.toymoban.com/news/detail-419670.html

到了这里,关于安卓实现M3U8文件的下载和播放的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于 Web 实现 m3u8 视频播放的简单应用示例

    将视频(MP4 等)转换为 M3U8 视频的服务,可以按照以下步骤进行操作: 将视频(MP4 等)转换为 M3U8:在服务中,使用适当的工具(如 FFmpeg)将接收到的视频(MP4 等)转换为 M3U8 格式。这将生成一个包含视频流的 M3U8 文件以及相应的分段(TS)文件。 提供边下边播服务:将生

    2024年02月07日
    浏览(37)
  • Python 实现 m3u8 视频下载

    m3u8 是一种 基于文本的媒体播放列表文件格式 ,通常用于指定流媒体播放器播放在线媒体流。它是一个简单的文本文件,其中包含多个由 URI 引用的媒体资源文件的 URL。m3u8 文件通常包含多个 ts 文件的链接,这些 ts 文件是实际的视频和音频数据文件,通常是通过 HTTP 协议传

    2024年02月07日
    浏览(53)
  • 前端实现H265编码的m3u8视频流播放

    前言 视频监控是智慧城市、智慧园区等WebGIS类系统中最为常见的硬件对接设备,最常用的监控视频流格式为m3u8格式,但是m3u8格式通常都是h.265编码格式的,我搜遍了几乎所有前端视频播放插件,几乎普通的播放器插件都不支持h.265格式的视频编码。本文就带领大家了解H265视

    2024年01月18日
    浏览(52)
  • vue使用video.js实现播放m3u8格式的视频

    我使用的video.js版本如下: 在components下新建一个VideoPlayer文件夹 index如下:  直接把地址传给sourceUrl即可

    2024年02月12日
    浏览(46)
  • html5播放 m3u8

    注意:m3u8地址要为网络地址,直接把代码复制为html直接在本地打开,可能不行,需要放在nginx或者apache或者其他的web服务器上运行。

    2024年02月20日
    浏览(34)
  • 视频防盗链下载,ffmpeg转m3u8,ts实现视频切片

    最近公司有个需求,要求付费的大视频防止下载,不卡顿功能。 优先使用的是阿里的视频点播,自己琢磨没事干,网上很多电影视频网站是如何做到的呢,然后就是各种搜,得到了一下结果 这个video标签的src地址是下载不了的,这下和电影网站的一样了

    2023年04月26日
    浏览(43)
  • uniapp 直播拉流 播放m3u8 视频

    在百度中找啦n多个方法 没有解决啦 巨气人 发现hls.js hls.js不需要任何播放器,它可以直接在标准HTML 元素上运行。 安装第三方库 在uniapp页面显示 如果想要应用在自己的页面中 直接c v 就ok啦 要是有人问推流为啥没有 不要问 问就是不会!!!

    2024年02月12日
    浏览(47)
  • vue项目如何播放m3u8格式视频

    在node_modeols里面找到@easydarwin下的dist/compent/EasyPlayer-lib.min.js和EasyPlayer.wasm两个文件复制到pubilc目录下 引入 在components中 在模板中

    2024年02月15日
    浏览(53)
  • video插件播放m3u8格式视频(存原生)

    这里使用原生的javascript实现m3u8格式视频播放。 使用了包括video.min.js库和HLS插件。 在上面代码中,首先引入了video.min.js库和对应的播放器样式video-js.css,还引入了videojs-contrib-hls.min.js库(引入顺序考虑优先放到页面加载之前)。 之后,创建一个video标签,并指定source的src属性为

    2024年02月13日
    浏览(49)
  • Unity WebGL 播放视频流m3u8

    目录 介绍 步骤 1.导入AVProVideo插件,创建场景,创建空物体添加MediaPlayer组件设置m3u8视频地址以及WebGL平台设置  2.在Canvas下创建Avpro Video,为MediaPlayer赋值  3.可以现在编辑器模式下测试视频地址是否可以播放,然后打包  4.打包完成后,将文件hls.min.js复制到Build文件夹下: 5

    2023年04月10日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包