m3u8视频流,视频切片处理

发布时间:2024年01月11日

为什么要用m3u8而不是mp4

随着客户的增加,mp4文件播放的弊端也日益凸显。

mp4缺点

1):mp4的关键帧元素往往很大,需要加载很长时间才能开始播放。
2):当用户打开一个视频播放的时候,浏览器会持续请求下载mp4文件直到下载完成,就算是用户暂停视频播放浏览器也会持续这种下载状态,给服务器硬盘和宽带造成很大浪费和压力。

选用m3u8

而m3u8视频流则是吧一个大的视频文件按照一定大小或时长把一个视频分为N段播放,这样打开视频加载速度快,可以达到秒播,而且当视频播放第N段的时候,浏览器会下载N+1段,N+2则不会下载,大大缓解了服务器硬盘和宽带压力。

什么是m3u8

m3u8是苹果公司开发的一项新型播放格式,这种播放格式支持目前市面的windows、androis、ios设备主流的浏览器,同样的视频文件既可以在flash环境播放,又能在无flash的html5环境播放,它的优势还不止于此,它可以实现多种码率在不同网速下的自动切换,网速好自动切换高清晰度视频,网速慢自动播放低清晰度文件,还可以实现流加密(视频文件本身加密)、分段下载播放、任意时间点拖拽播放、随机视频文件广告插入等等优势,所以最新版的云转码视频系统仅把m3u8作为唯一的播放格式而放弃了其他格式的输出。

将mp4视频转换为m3u8视频流

方法/步骤

主流的方式是通过 m3u8格式视频转码工具 FFmpeg 来实现的

下载
从我个人百度网盘下载:https://pan.baidu.com/s/17Hkccz4w1qxHd2bPJsslOg?pwd=wpcd
提取码:wpcd

下载完解压后可以在bin文件嘉下看到三个可执行文件,
在这里插入图片描述
配置环境变量,找到path编辑并添加刚刚bin目录复制进去

在这里插入图片描述

在cmd中输入ffmpeg 没有报错则表示安装成功

在这里插入图片描述

视频分割命令

 ffmpeg -i video1.mp4 -profile:v  baseline -level 3.0 -start_number 0 -hls_time 1 -hls_list_size 0 -f hls demo.m3u8
  1. -i 指定输入的文件名
  2. -profile:v baseline 大概意思是档次转成基本画质,有四种画质级别,分别是baseline, extended, main, high,从低到高
  3. -level 3.0 大概也是视频画质级别吧,基本上是从1到5,
  4. -start_number 0 表示从0开始
  5. -hls_time 1 标识每1秒切一个
  6. -f hls 将视频转为hls格式
  7. -hls_list_size 0设置播放列表保存的最多条目,设置为 0 会保存有所片信息,默认值为5。

成功后可以得到下面的文件

在这里插入图片描述

注意:

ts文件的切割还与两个帧之间的时间间隔有关,任何一个ts分片的第一帧必须是1帧,否则无法进行播放。因此有时候并不会按照指定的时间进行分割

解决

既然知道要1秒产生一个ts分片,那就必须产生切片的过程中,强制一秒中产生一个关键帧。设置关键帧间隔,设置间隔为 2 秒的参数如下:-force_key_frames "expr:gte(t,n_forced*2)"

 ffmpeg -i video1.mp4 -force_key_frames "expr:gte(t,n_forced*2)" -profile:v  baseline -level 3.0 -start_number 0 -hls_time 1 -hls_list_size 0 -f hls demo.m3u8

视频合并

将视频合并成一个完整的mp4可以执行以下命令

ffmpeg -i demo.m3u8 -c copy abc.mp4

注意:demo.m3u8里必须完整记录的这个视频的信息

例如:

在这里插入图片描述

前端播放m3u8视频流(vue3示例)

安装依赖

npm install --save video.js
npm install --save videojs-contrib-hls

在需要的组件中引入

import 'video.js/dist/video-js.css';
import videojs from 'video.js';
import 'videojs-contrib-hls';

使用demo

// html部分
<video controls autoplay preload="auto" :fluid="true"  ref="videoPlayer" class="video-js video" />

// js部分
const videoPlayer = ref(null) // video标签
const myPlayer = ref<any>(null)
const setVideoUrl = (url: string)=>{
    nextTick(() => {
        myPlayer.value = videojs(videoPlayer.value, {
            sources: [
                {
                    src: url,//视频地址
                    type: 'application/x-mpegURL'
                }
            ],
            controlBar: {
                timeDivider: false,//当前时间和持续时间的分隔符
                durationDisplay: false,//显示持续时间
                remainingTimeDisplay: true,//是否显示剩余时间功能
                currentTimeDisplay: false,//当前时间
                volumeControl: false,//音量控制键
                playToggle: true,//播放按钮
                progressControl: true,//进度条
                fullscreenToggle: true,//全屏按钮
            },
        })
    })
}

问题

服务器上的m3u8视频在播放时会有跨域错误,详细可以查我的m3u8解决跨域这片文章,针对IIS和Nginx都有相关解决方案。

文章来源:https://blog.csdn.net/qq_51279669/article/details/135422280
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。