前端如何实现整套视频直播源码的技术流程

前端如何实现整套视频直播源码的技术流程

下面按照目录大纲来一个一个讲解。

1. 直播技术的介绍

直播技术涵盖很广,现如今大家广泛了解的就有视频网站的个人直播、手机直播、安防方面的摄像头监控等会使用到直播的技术。

下面先出一张概念图,介绍直播流程中的各个技术环节。可以理解分为采集端、流媒体服务器以及播放端;还需要了解什么是推流,什么是拉流。

前端如何实现整套视频直播源码的技术流程_第1张图片

 

  • 采集端:顾名思义是视频的源头,视频的采集一般都是从真实的摄像头中得到的。例如移动端设别、PC端设备的摄像头以及一些摄像头设备;
  • 流媒体服务器:流媒体服务器是整个直播技术框架的非常重要的一环,它需要接收从采集端推上来的视频流,然后将该视频流再推送到播放端;
  • 播放端:播放端就是各种app,网页中的播放器,拉取流媒体服务器上的视频流,然后进行转码,最终播放出来;
  • 推流:把采集阶段收集的数据封装好传输到服务器的过程;
  • 拉流:服务器已有直播内容,用指定地址进行拉取的过程。

既然需要推流和拉流,就必然涉及到视频流的传输,所以接下来介绍常用的流媒体传输协议 常用的流媒体传输协议有RTMP, RTSP,HLS和HTTP-FLV。

  •  

RTMP (可用于推流端和拉流端)
Real Time Messaging Protocol,实时消息传输协议。RTMP协议中,视频必须是H264编码,音频必须是AAC或MP3编码,且多以flv格式封包。因为RTMP协议传输的基本是FLV格式的流文件,必须使用flash播放器才能播放。

  •  
  •  

RTSP (用于推流端)
Real-Time Stream Protocol,RTSP实时效果非常好,适合视频聊天、视频监控等方向。

  •  
  •  

HLS (用于拉流端)
Http Live Streaming,由Apple公司定义的基于HTTP的流媒体实时传输协议。传输内容包括两部分:1.M3U8描述文件;2.TS媒体文件。TS媒体文件中的视频必须是H264编码,音频必须是AAC或MP3编码。数据通过HTTP协议传输。目前video.js库支持该格式文件的播放。

  •  
  •  

HTTP-FLV (用于拉流端)
本协议就是http+flv,将音视频数据封装成FLV格式,然后通过http协议传输到客户端,这个协议大大方便了浏览器客户端播放直播视频流。目前flv.js库支持该格式的文件播放。

  •  

有了以上基本概念之后,我们就大致知道要搭建一个拥有直播功能的页面需要哪些东西了,下面就基于这个架构进行各个部分的实现。

前端如何实现整套视频直播源码的技术流程

2. 前端搭建使用的技术

  •  

搭建流媒体服务

  •  

提到流媒体服务器,其实作为开发前端的人来说,本人一开始也是无所适从的,不知道这个东西该怎么实现或者要用什么语言去写。首先想到的肯定是搜索现有的实现技术,看看是否能够通过纯前端去实现。纯JS技术的话,肯定首先想到了node.js,于是就使用“node.js + 视频流媒体技术实现方案”的关键词去搜索,获得了一个看着比较靠谱的结果:NodeMediaServer,然后去看介绍发现是基于node去实现的一个开源的流媒体服务器,虽然最新版本已经使用go去重构了,但是毕竟历史上它是由node来开发的,所以决定看文档试一试搭建一个这样的服务器。请参考NodeMediaServer官网

  •  

NodeMediaServer支持:以rtmp、rtsp、hls协议拉进行推流,支持http-flv,ws-flv来进行拉流,也就是支持浏览器端使用http或websocket传输flv格式的视频流进行播放。

  •  

开始搭建流媒体服务器:

    • 下载对应的安装包,使用的Linux环境
      下载:

wget https://cdn.nodemedia.cn/nms/3.2.12/nms-linux-amd64-20200222.tar.gz复制代码

    • 解压:

tar -zxvf nms-linux-amd64-20200222.tar.gz复制代码

    •  

到解压后的目录下,执行命令,启动服务:

    •  

在控制台输入./nms运行

    •  
    •  

在当前程序目录下执行sudo ./service.sh install安装服务并自动运行

    •  
    •  

在当前程序目录下执行sudo ./service.sh uninstall停止并卸载服务å

    •  
    •  

服务成功启动之后,可以在8000端口(默认端口)访问流媒体服务的后台系统,这里面大概长下面这个样子:

    •  
    • 前端如何实现整套视频直播源码的技术流程_第2张图片前端如何实现整套视频直播源码的技术流程_第3张图片
    •  

首页dashboard展示了服务器cpu的使用情况以及网络带宽状况。

  •  

服务启动之后,接下来要做的是推流

  •  

怎么推流?这里涉及到一个很强大的东西ffmpeg,它是可以用来记录、转换数字音视频,并将其转化为流的开源软件,通过它可以进行视频的采集封装成流,并推送到流媒体服务器,例如在mac上面安装了这个软件之后,可以通过它调用摄像头,并将摄像头数据封装成流后推送到流媒体服务器,这个过程就是推流。ffmpeg还可以推送本地的视频文件到流媒体服务器。

  •  

使用ffmpeg进行mac本地摄像头实时推流到nodeMediaServer:

  •  

ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -i 0:0 -vcodec libx264 -preset veryfast -f flv http://ip:8000/live/stream.flv复制代码

  •  

这里涉及到ffmpe工具,上面的参数不逐一解释,只是最重要的几个:

    • ·-vide_size表示要输出的视频画面的分辨率尺寸
    • -f后面的参数 flv表述输出的格式,再后面的地址 http://ip:8000/live/stream.flv 表示想要输出的地址,这个地址的stream.flv可以按照自己需求随意修改,保持后缀是你需要的flv格式即可。

另外一种常用的场景是直接拉去摄像头设备中的视频流数据,这种方式,nodeMediaServer也支持,只需要在管理后台配置对应的摄像头的配置信息,就可以进行推流操作了。这些配置信息包括ip,登录用户名和密码等。配置界面如下所示:

预设配置:前端如何实现整套视频直播源码的技术流程_第4张图片前端如何实现整套视频直播源码的技术流程_第5张图片

 

还可以自定义设定配置,如果使用的是自定义的摄像头,具备rtsp传输功能的,就可以使用西面的配置方式进行摄像头信息的配置,指定输出流地址,这样直接从浏览器端就可以通过这个输出流地址进行视频的播放:

前端如何实现整套视频直播源码的技术流程_第6张图片

  • 前端如何实现整套视频直播源码的技术流程_第7张图片

前端页面支持播放视频流

  •  

前端页面部分,首要目标是找到支持http-flv和ws-flv协议格式的前端播放器,首先去观察了B站的直播,发现他们的直播页面是使用的video标签,后来进一步发掘,才知道他们用的是自己开源的flv.js库,这是一个支持在浏览器端进行http-flv及ws-flv格式的视频流进行播放的播放器,正好是播放直播视频流需要的。

  •  

视频流有了,那么就可以使用flv.js来搭建页面demo,查看实际效果了。

前端如何实现整套视频直播源码的技术流程

3. 实践效果

  •  

首先搞定推流:

  •  

分别实验了直接从mac上推摄像头的视频流数据以及绑定摄像头设备地址信息,通过nodeMediaServer进行推流和拉流服务。

  •  
  •  

然后是前端页面进行视频流的播放,下面是播放器部分的核心代码:

  •  

live-demo.js

  •  

import * as React from 'react';

import { Button, Input, Row, Col } from 'react-x-component';import flv from 'flv.js';

const { useState, useEffect } = React;

 

interface LiveDemoProps {

    defaultUrl?: string,

    onUrlChange?: Function

}

export default function LiveDemo({ defaultUrl = 'http://ip:8000/live/stream.flv', onUrlChange }: LiveDemoProps) {

 

    let player = null;

    let playerDom = null;

    

    const [liveUrl, setLiveUrl] = useState(defaultUrl);

    

    useEffect(() => {

        if (flv.isSupported) {

            player = flv.createPlayer({

                type: 'flv',

                isLive: true,

                hasAudio: false,

                hasVideo: true,

                url: liveUrl,

                cors: true

            }, {

                enableWorker: false,

                lazyLoadMaxDuration: 3 * 60,

                seekType: 'range'

            });

            player.attachMediaElement(playerDom);

            player.load();

    

        } else {

            console.log('Your browser is not support flv.js');

        }

    }, []);

    

    function updatePlayer() {

        if (player) {

            player.unload();

            player.detachMediaElement();

            player.destroy();

            player = null;

        }

    

        player = flv.createPlayer({

            type: 'flv',

            isLive: true,

            hasAudio: false,

            hasVideo: true,

            url: liveUrl,

            cors: true

        }, {

            enableWorker: false,

            lazyLoadMaxDuration: 3 * 60,

            seekType: 'range'

        });

        player.attachMediaElement(playerDom);

        player.load();

    }

    

    return (

        

            

                

                    

                        

                            value={liveUrl}

                            onChange={(value) => {

                                setLiveUrl(value);

                            }}

                        />

                    

                    

                        

                            type={'primary'}

                            onClick={() => {

                                updatePlayer();

                                onUrlChange && onUrlChange(liveUrl);

                            }}

                        >修改

                    

                

            

            

                style={{ width: '100%', height: '100%' }}

                controls

                className='video-demo'

                ref={(e) => playerDom = e}

            >

        

    );

}复制代码

  •  
  •  

播放摄像头的视频流效果,左边是直接获取的摄像头数据流,右边是通过mac电脑推的实时的摄像头画面:

  •  
  •  

OK,这样就搞定了一整套直播网页需要的前后端技术服务的搭建了!

4. 后续需要继续继续实践和探索的内容

上面的示例相对而言还过于简单,只是借助了第三方的技术和框架搭建了一个流媒体服务器,和前端支持播放视频流的播放页面,并通过摄像头采集数据,推流,打通了整个流程,形成了一个闭环,但是还有很多内容需要进一步深入:

  • 视频信息实时处理,如何添加更多的信息
  • 高并发场景是如何去实现的,流媒体服务器这块的实现还是过于简单,肯定还有需要分发处理的机制
  • 浏览器播放性能需要进行压力测试
  •  
  •  
  • 前端如何实现整套视频直播源码的技术流程

总结

本文通过概念学习和介绍,理解了常见视频直播技术的整体架构流程,基于前端的角度去快速搭建了一套完整的直播网页的功能,当然其中还有很多不足和需要深入的地方,需要进一步探索,后续如果有更深入的技术沉淀,会继续形成文章进行分享!

 

你可能感兴趣的:(直播系统开发,直播平台开发,直播源码)