音视频直播原理解析

news/2024/9/22 21:35:21/

直播原理就是一个推流和拉取流的过程;

直播端将直播流推送至服务器,用户端发起请求从服务器拉取直播流然后解码播放

第一部分就是视频直播端的操作:视频采集处理后推流到流媒体服务器。

  • 首先从前端采集设备中获得原始的音频、视频数据;
  • 为了增强额外效果,对音频进行混音、降噪等处理,可为视频打上时间戳、添加Logo水印或增加滤镜;
  • 随后对音频、视频进行编码,通过编码压缩满足其在互联网上实时传输的需求;
  • 编码后就可以把各种多媒体内容(视频、音频、字幕等)盛放在同一个容器里,也就是所谓的封装,使得不同多媒体内容可同步播放,与此同时还提供了索引;
  • 最后就是通过流传输协议将封装好的内容推送到流媒体服务器上;

第二部分就是流媒体服务器:负责把从第一部分接收到的流进行处理并分发给用户。

流媒体服务器的主要功能是对流媒体内容进行采集(接收推流)、缓存、调度和传输播放(以流式协议实现用户分发)。

第三部分就是用户端:只需要拥有支持对应流媒体传输协议的播放器即可。

这一部分其实就是我们前端需要实现的,如何在移动端的内嵌h5页面中实现直播流的播放。所以我们只需要关注后端是通过什么协议给我们返回直播流以及我们如何有效的播放就可以了~

哪些流媒体传输协议用于直播,不同类型之间又有什么区别?

  • RTMP(Real Time Messaging Protocol)

协议比较全能,既可以用来推送,又可以用来直播。其核心理念是将大块的视频帧和音频帧“剁碎”,然后以小数据包的形式在互联网上进行传输,且支持加密,因此隐私性相对比较理想,但拆包组包的过程比较复杂,所以在海量并发时容易出现一些不可预期的稳定性问题。

  • HLS(HTTP Live Streaming)

苹果推出的解决方案,将视频分成 5-10 秒的视频小分片,然后用 M3U8 索引表进行管理。由于客户端下载到的视频都是 5-10 秒的完整数据,故视频的流畅性很好,但也同样引入了很大的延迟(HLS 的一般延迟在 10-30s 左右)。相比于 FLV,HLS 在iPhone 和大部分 Android 手机浏览器上的支持非常给力,所以常用于 QQ 和微信朋友圈的 URL 分享。

  • HTTP-FLV(Flash Video)

由 Adobe 公司主推,格式极其简单,只是在大块的视频帧和音视频头部加入一些标记头信息,由于这种极致的简洁,在延迟表现和大规模并发方面都很成熟。唯一的不足就是在手机浏览器上的支持非常有限,但是用作手机端 APP 直播协议却异常合适。

RTMP、HLS、HTTP-FLV 协议对比如下图所示:

移动端内嵌h5实现视频直播

1、技术选型:

  • 传输协议——由于后端支持同时返回HLS协议和RTMP协议的直播流,结合考虑HLS协议的高延时问题和RTMP协议的兼容性问题,本项目决定采用向下兼容的方式实现,默认使用RTMP协议直播,当浏览器不支持时降级使用HLS协议播放。
  • 直播插件——本项目基于Vue实现,并且业务逻辑为常规直播操作,无特殊需求,从开发效率、稳定性及兼容性出发,决定采用vue-video-player插件实现。

2、vue-video-player安装与引入:

  • CDN:
<link rel="stylesheet" href="path/to/video.js/dist/video-js.css"/>
<script type="text/javascript" src="path/to/video.min.js"></script>
<script type="text/javascript" src="path/to/vue.min.js"></script>
<script type="text/javascript" src="path/to/dist/vue-video-player.js"></script>
<script type="text/javascript">Vue.use(window.VueVideoPlayer)
</script>
  • NPM(支持全局/按需引入):npm install vue-video-player --save

全局引入

import Vue from 'vue'
import VueVideoPlayer from 'vue-video-player'// 引入videojs样式
import 'video.js/dist/video-js.css'
// 自定义样式引入,并为<video-player>添加对应类名即可,例如vjs-custom-skin
// import 'vue-video-player/src/custom-theme.css'Vue.use(VueVideoPlayer, /* {options: 全局默认配置,events: 全局videojs事件
} */)

按需引入

// 引入videojs样式
import 'video.js/dist/video-js.css'import { videoPlayer } from 'vue-video-player'export default {components: {videoPlayer}
}

3、video.js插件扩展: 当已有插件无法满足需求时可对已有插件进行扩展或自行开发video.js插件

import videojs from 'video.js'// videojs plugin
const Plugin = videojs.getPlugin('plugin')
class ExamplePlugin extends Plugin {// something...
}
videojs.registerPlugin('examplePlugin', ExamplePlugin)// videojs language
videojs.addLanguage('es', {Pause: 'Pausa',// something...
})// more videojs api...// vue component...

4、视频直播关键代码:
options:video.js options
playsinline:设置播放器在移动设备上不全屏[ Boolean, default: false ]
customEventName:自定义状态变更时的事件名[ String, default: 'statechanged' ]

<template><video-playerclass="video-player-box"ref="videoPlayer":options="playerOptions":playsinline="true"customEventName="customstatechangedeventname"@play="onPlayerPlay($event)"@pause="onPlayerPause($event)"@ended="onPlayerEnded($event)"@waiting="onPlayerWaiting($event)"@playing="onPlayerPlaying($event)"@loadeddata="onPlayerLoadeddata($event)"@timeupdate="onPlayerTimeupdate($event)"@canplay="onPlayerCanplay($event)"@canplaythrough="onPlayerCanplaythrough($event)"@statechanged="playerStateChanged($event)"@ready="playerReadied"></video-player>
</template>
export default {data() {return {playerOptions: {// 是否关闭音频muted: true,// 初始语言,默认为英语,code参见:https://www.iana.org/assignments/language-subtag-registry/language-subtag-registrylanguage: 'zh-CN',// 播放速度,指定后Video.js将显示一个控件(vjs-playback-rate类的控件),允许用户从选项数组中选择播放速度playbackRates: [0.5, 1.0, 1.5, 2.0],// 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值,表示长宽比例aspectRatio: '4:3',// 等同于原生<video>标签中的一组<source>子标签,可实现优雅降级;type 属性规定媒体资源的 MIME 类型,标准类型可参见:https://www.iana.org/assignments/media-types/media-types.xhtml;sources: [{type: "rtmp/flv",src: "rtmp://58.200.131.2:1935/livetv/hunantv"}, {type: "application/x-mpegURL",src: "http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8"}],// 兼容顺序,默认值是['html5'],这意味着html5技术是首选,其他已注册的技术将按其注册的顺序在该技术之后添加。techOrder: ['flash'],// 在视频开始播放之前显示的图像的URL(封面),这通常是一个视频帧或自定义标题屏幕,一旦用户点击“播放”,图像就会消失。poster: require('../assets/test.jpg'),}}},mounted() {console.log('this is current player instance object', this.player)},computed: {player() {return this.$refs.videoPlayer.player}},methods: {// 各个事件监听onPlayerPlay(player) {// console.log('播放器播放!', player)},onPlayerPause(player) {// console.log('播放器暂停!', player)},// ...(此处省略多个事件监听函数)// 状态监听playerStateChanged(playerCurrentState) {// console.log('播放器当前状态更新', playerCurrentState)},// 监听播放器是否就绪playerReadied(player) {console.log('播放器已就绪', player)// 就绪后就可以调用播放器的一些方法}}}

踩坑小tips:
播放 HLS 协议流,需要videojs-contrib-hls插件,但是直接引用即可,因为在安装vue-video-player插件时,videojs-contrib-hls是一并安装的;如果需要播放RTMP协议流,需要videojs-flash插件,也是直接引用就可以了(flash插件需要在hls之前引用)

import 'videojs-flash'
import 'videojs-contrib-hls'

http://www.ppmy.cn/news/1439940.html

相关文章

架构师系统-Docker(六)-镜像仓库Harbor支持Https(扩展)

Harbor支持Https(扩展) 为了支持微服务推送我们需要将HarBor设置为https&#xff0c;可以让HarBor在任何地方使用以及推送 前面说了怎么搭建harbor仓库&#xff0c;这里讲一讲harbor实现https访问&#xff0c;因为只需要内网访问&#xff0c;没必要去申请一个ssl证书&#xff0…

SpringMVC中的文件上传和中英文名称文件下载

一、文件上传 前端&#xff1a; <% page language"java" contentType"text/html;charsetUTF-8"pageEncoding"UTF-8"%> <! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4…

C++ Primer Plus

第一章 初始C #include <iostream> //#:预处理int main(void) //void:无参数 {using namespace std;int carrots; //定义声明语句:开辟内存空间&#xff0c; int:整型 cout << "how many corrots do you have?" << endl; //cout:输出流(out) end…

C语言Linux vim shell命令

无论是在插入模式或者是其他模式下对于文件的修改都是对于内存缓冲区进行修改&#xff0c;只有当点击w进行保存以后才会将数据写入到一个新的文件中的&#xff0c;将源文件删除&#xff0c;并且新文件改为文件的名字 1. actionmotion dG删到文件尾 ggdG先到开头再删除到末尾…

微信小程序:12.页面导航

什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现的页面导航的方式有两种&#xff1a; 连接location.href 小程序中实现页面导航的两种方式 声明式导航 在页面上声明一个导航组件 通过点击组件实现页面跳转 导航TabBar页面 是指配置TabB…

公钥密码学Public-Key Cryptography

公钥或非对称密码学的发展是整个密码学历史上最伟大的&#xff0c;也许是唯一真正的革命。The development of public-key, or asymmetric, cryptography is the greatest and perhaps the only true revolution in the entire history of cryptography. 公钥算法基于数学函数…

SpringBoot学习之Kafka发送消费消息入门实例(三十五)

使用Kafka之前需要先启动fKafka,如何下载安装启动kafka请先参考本篇文章的前两篇: 《SpringBoot学习之Kafka下载安装和启动【Windows版本】(三十四)》 《SpringBoot学习之Kafka下载安装和启动【Mac版本】(三十三)》 一、POM依赖 1、加入kafka依赖 2、我的整个POM代码…

【计算机毕业设计】基于SSM++jsp的校园快递代取系统【源码+lw+部署文档+讲解】

目录 1 绪论 1.1 研究背景 1.2 目的和意义 1.3 论文结构安排 2 相关技术 2.1 SSM框架介绍 2.2 B/S结构介绍 2.3 Mysql数据库介绍 3 系统分析 3.1 系统可行性分析 3.1.1 技术可行性分析 3.1.2 经济可行性分析 3.1.3 运行可行性分析 3.2 系统性能分析 3.2.1 易用性指标 3.2.2 可…