20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析

1.vue中的video的使用(支持MP4)

Vue中引入Video.js视频播放器

参考:https://www.jianshu.com/p/8b8023c7ed37 

Video.js是一个有着HTML5背景的网络视频播放器。它同时支持HTM5和Flash视频,简单来说就是HTMl5 和 Flash 视频播放器

安装

 $ npm install video.js

main.js中引入

import Video from 'video.js'
import 'video.js/dist/video-js.css'

Vue.prototype.$video = Video

使用(代码中有注释说明)

    

    

    

实现效果截图

2.vue中的video的使用(支持rtmp)

参考链接:https://www.jianshu.com/p/fede1032bc16

20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析_第1张图片

  • style =“width:100%; height:100%; object-fit:fill”的作用是使播放器自适应其父元素的大小

  • 静音:实现静音播放,有一些浏览器需要静音才能实现加载之后自动播放

  • controls:将显示视频控件,如果不需要则去掉控制即可。

  • autoplay:视频在加载完成之后自动播放; 注意,这里在Chrome62.X上有坑,如果播放器大小小于400 * 300的话是不会自动播放的。

  • poster:视频封面图片;

  • loop:true / false,是否循环播放

  • 实例化视频
  • 实例化视频
  • 
    CreatePlayer(id) {
    
                var options = {
                    autoplay : true,
                    preload : true,
                    falsh: {
                        swf: './lib/video-js.swf'
                    }
                }
    
                let self = this;
    
                return videojs(id, options, function onPlayerReady() {
                    videojs.log(`Your player${self.index} is ready!`);
    
                    // How about an event listener?
                    this.on('ended', function() {
                        videojs.log('Awww...over so soon?!');
                    });
    
                    this.on('error', function() {
                        console.log('error');
                    })
    
                    this.on("abort", function() {
                        console.log("abort");
                    });
    
                    this.on("emptied", function() {
                        console.log("emptied");
                    });
    
                    this.on('loadstart', () => {
                        self.player.play();
                    });
    
                    this.on('stalled ', function() {
                        console.log("stalled");
                    });
                });
            }
    

    videoJs()接收三个参数,DOM元素的ID,videoJs的配置,以及一个回调函数。

  • 播放
  • 
    playVideo(url) {
                this.player = this.CreatePlayer(this._id);
                this.player.src({
                    src : url,
                    type: 'rtmp/flv',
                    autoplay: true,
                    isFullscreen: true
                });
            }

     

  • 全屏切换(浏览器不允许使用函数全屏,一定要用户有操作触发)
  • 进入全屏,需要参入要全屏的DOM元素即包裹视频的盒子
  • enterFullScreen(ele) {
    
                if (ele .requestFullscreen) {
                    ele .requestFullscreen();
                } else if (ele .mozRequestFullScreen) {
                    ele .mozRequestFullScreen();
                } else if (ele .webkitRequestFullScreen) {
                    ele .webkitRequestFullScreen();
                }
            }
    
  • 退出全屏
  • 
    exitFullscreen() {
                var de = document;
                if (de.exitFullscreen) {
                    de.exitFullscreen();
                } else if (de.mozCancelFullScreen) {
                    de.mozCancelFullScreen();
                } else if (de.webkitCancelFullScreen) {
                    de.webkitCancelFullScreen();
                }
            }
    
  • 控制视频正中的播放按钮
  • 
    $('.vjs-big-play-button') // 获取该dom元素
    
  • 取消播放
    videoJs提供一个api --- video.dispose()
    但是使用dispose会将整个视频从dom中移除,之后无法再重新播放视频
    所以我们先把视频标签保存起来
  • self.player.dispose();
    let _id = self._id;
    let video_dom = "";
    
    // 将video标签重新插入html
    $('#' + self.mask_id).before(video_dom);
    

    然后便可以重新实例化videojs,加载url播放视频

  • 问题:videojs提示(代码:4 MEDIA_ERR_SRC_NOT_SUPPORTED)此视频未找到兼容的来源。
  • 解决:

    image.png


    选择网站设置,将flash设置为允许(chrome默认不让flash播放)

    image.png

     

  • 问题:videojs标签大小小于400 * 300时不会自动播放
  • 解决:将flash.swf下载到本地,从本地加载。设置videojs.options.flash =“本地swf文件地址”; 如果设置不成功,可以直接修改video.js里面的配置。

    image.png


    整理后的发现(关于vue中的video.js支持rtmp):

  • 1.vue中的video是支持rtmp播放的,只要rtmp是可以正常播放即可(nginx有推流的情况);

  • 2.不是每次用才去推流的,最好刚开始就把所有流都开启,用的时候直接放rtmp拉流即可。

 

以下是关于nginx推流和拉流的疑惑分析:

参考:https://cloud.tencent.com/developer/article/1336238

3.nginx服务器以及实现推流和拉流

几个名词的解释:

Nginx:
    Nginx是一款轻量级服务器/反向代理服务器及电子邮件代理服务器,并在一个BSD-like 协议下发行。
    其特点是占有内存少,并发能力强

RTMP:
    RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间
    音频、视频和数据传输 开发的开放协议。.这个协议建立在TCP协议或者轮询HTTP协议之上,是一个协议族,
    包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种
    它有多种变种:
    1)RTMP工作在TCP之上,默认使用端口1935;
    2)RTMPE在RTMP的基础上增加了加密功能;
    3)RTMPT封装在 HTTP请求之上,可穿透 防火墙;
    4)RTMPS类似RTMPT,增加了TLS/SSL的安全功能;
ffmpeg:
    FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。
    项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。
H.264:

    H.264最大的优势是具有很高的数据压缩比率,在同等图像质量的条件下,H.264的压缩比是MPEG-2的2倍以上,
    是MPEG-4的1.5~2倍。举个例子,原始文件的大小如果为88GB,采用MPEG-2压缩标准压缩后变成3.5GB,压缩比为25∶1,
    而采用H.264压缩标准压缩后变为879MB,从88GB到879MB,H.264的压缩比达到惊人的102∶1。
    ## H264是一种高压缩率的编码标准,如何压缩嘞?一般的视频采集都是25帧/秒,
    ## 也就是每秒截图25次,其实每一张图片的内容都相差不大,压缩的办法就是利用算法,
    ## 只将每张图片变动差异化的部分保存下来,这样视频文件就小多了

    低码率(Low Bit Rate)对H.264的高的压缩比起到了重要的作用,和MPEG-2和MPEG-4 ASP等压缩技术相比,
    H.264压缩技术将大大节省用户的下载时间和数据流量收费。
    尤其值得一提的是,H.264在具有高压缩比的同时还拥有高质量流畅的图像,
    正因为如此,经过H.264压缩的视频数据,在网络传输过程中所需要的带宽更少,也更加经济。

    H.265是新的编码协议,也即是H.264的升级版。
    他们核心区别的可以分两步看:
    1同样的画质和同样的码率,H.265比H2.64 占用的存储空间要少理论50%。
    2如果存储空间一样大,那么意味着,在一样的码率下H.265会比H2.64 画质要高一些理论值是30%~40%
    据说能节省一半带宽,但需要机器更强的运算能力。

FFmpeg和h.264是什么关系?
     H.264是标准(包含编码、解码),x264是标准的实现(只实现了编码),ffmpeg是一个框架,
     但是里面包含了H.264的解码实现,所以ffmpeg + x264 就包含了H.264的编码、解码的实现了。

4.nginx的配置文件信息

vi /usr/local/etc/nginx/nginx.conf  
rtmp {  
  server {  
      listen 1935;  
    #直播流配置  
      application rtmplive {  
          live on;  
          #为 rtmp 引擎设置最大连接数。默认为 off  
          max_connections 1024;  
       }  
      application hls{  
          live on;  
          hls on;  
          hls_path /usr/local/var/www/hls;  
          hls_fragment 1s;  
      }  
   }  
}

nginx常用方法::

重新加载配置文件:  nginx -s reload
重新加载日志:     nginx -s reopen 
停止 nginx:      nginx -s stop  
有序退出 nginx:   nginx -s quit

5.本地推流

(1)、搭建本地视频直播,比如电脑上面有很多电影,我们可以通过推流的形式实现实时直播:

 

A:在电脑上播放推流内容

 

安装一个支持rtmp协议的视频播放器,Mac下可以用VLC

下载VLC 本地下载一个视频文件路径为 /Users/iOS002/Desktop/loginmovie.mp4 执行以下命令

ffmpeg -re -i /Users/iOS002/Desktop/loginmovie.mp4  -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/rtmplive/room

如果是javacv就用javacv的方式操作推流 

用vlc 然后打开 VLC 中 的 file -- Open Network, 直接输入代码中的 url:

rtmp://localhost:1935/rtmplive/room  (这个是推到nginx后的视频地址)

特别注意:必须是用推流工具ffmpeg或者javacv先把流推到nginx后,才能播放rtmp的视频

 

即可以通过VLC来播放终端中实时推过来的 RTMP流。

20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析_第2张图片

 

B:通过手机观看电脑的推流

 

通过集成 ijkplayer 把地址换成推流的地址即可观看:

播放端用的针对RTMP优化过的ijkplayer,ijkplayer是基于FFmpeg的跨平台播放器,这个开源项目已经被多个 App 使用,其中映客、美拍和斗鱼使用了 ijkplayer。

(2)、桌面录制或者分享

ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv rtmp://localhost:1935/rtmplive/room 

(3)、桌面+麦克风

ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/rtmplive/room

(4)、桌面+麦克风,并且还要摄像头拍摄到自己

ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480 -i "0" \-c:v libx264 -preset ultrafast \-filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:2016/rtmplive/room  

6.手机推流

可以用 LFLiveKit 集成到工程进行推流,LFLiveKit已经帮我们实现了视频采集、后台录制、美颜功能、支持h264、AAC编码,动态改变速率,RTMP传输等,我们开发的时候就很简单了只需把localhost:8080换成自己电脑的ip地址即可:

 rtmp://10.0.0.17:1935/rtmplive/room

20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析_第3张图片

注意通过网络查看电脑的局域网 IP替换掉 localhost 即可。

A:通过VLC观看手机的推流 打开手机直播后,然后在电脑上打开VLC(同上),就能实现手机推流,在电脑上拉流播放了!!(注:手机需要和电脑连接同一网络!)

20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析_第4张图片

B:通过手机观看手机的推流(这也就是市面上的那些直播App的最终实现形式了) 通过集成 ijkplayer 把地址换成推流的地址即可观看。

PS:一个很隐蔽的报错:

如果你发现你的推流地址和拉流地址在电脑上都是好好的,但是通过手机实现的时候就是报错,那么估计就是因为Mac防火墙的问题。

 

关闭 Mac 的防火墙即可解决问题。 20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析_第5张图片

以上关于nginx推流ffmpeg资料参考来源于大神:https://cloud.tencent.com/developer/article/1336238

 

7.javacv推流nginx-rtmp(重点研究)  ---

 

本机推流到nginx

 

前期实现:

之前的推流地址:直接拼接的rtmp和rtsp地址

如下:

rtsp://admin:123456Aa@192.168.1.44:554/Streaming/Channels/102

rtmp://192.168.1.113:1935/live/cal_20190218141704

rtmp://192.168.1.113:1935/live/cal_20190218141704

思路:javacv推流rtsp推到rtmp中,然后页面video中放的是url是rtmp地址。

代码如下:

    /**
     * 转流器 (不带弹出窗口的转流器)
     * @param inputFile
     * @param outputFile
     * @throws Exception
     * @throws FrameRecorder.Exception
     * @throws InterruptedException
     */
public static void recordPush1(String inputFile,String outputFile,int v_rs) throws Exception, FrameRecorder.Exception, InterruptedException{

    Loader.load(opencv_objdetect.class);
    long startTime=0;

    FrameGrabber grabber =FFmpegFrameGrabber.createDefault(inputFile);
    System.out.println("开始获取FrameGrabber grabber:"+grabber);

    try {
        System.out.println("获取 grabber的start:"+grabber);
        grabber.setImageHeight(480);
        grabber.setImageWidth(860);
        grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式,不然会丢包很严重
        grabber.start();
    } catch (Exception e) {
        try {
            System.out.println("获取 grabber的restart:"+grabber);
            grabber.restart();
        } catch (Exception e1) {
            System.out.println("出错了:"+grabber);
            throw e;
        }
    }
    System.out.println("结束获取FrameGrabber grabber:"+grabber);

    OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
    System.out.println("开始获取OpenCVFrameConverter.ToIplImage:"+converter);

    Frame grabframe =grabber.grab();
    opencv_core.IplImage grabbedImage =null;
    if(grabframe!=null){
        System.out.println("取到第一帧");
        grabbedImage = converter.convert(grabframe);
    }else{
        System.out.println("没有取到第一帧");
    }

    System.out.println("结束获取converter:"+converter);

    //如果想要保存图片,可以使用 opencv_imgcodecs.cvSaveImage("hello.jpg", grabbedImage);来保存图片
    FrameRecorder recorder;
    try {
        recorder = FrameRecorder.createDefault(outputFile, 500, 500);
    } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
        throw e;
    }

    recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264
    recorder.setFormat("flv");
    recorder.setFrameRate(v_rs);
    recorder.setGopSize(v_rs);

    System.out.println("准备开始推流..."+inputFile);
    try {
        recorder.start();
    } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
        try {
            System.out.println("录制器启动失败,正在重新启动..."+outputFile);
            if(recorder!=null)
            {
                System.out.println("尝试关闭录制器"+outputFile);
                recorder.stop();
                System.out.println("尝试重新开启录制器"+outputFile);
                recorder.start();
            }

        } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {
            throw e;
        }
    }

    System.out.println("开始推流"+inputFile+"/"+outputFile);
    //获取每一帧不展示

    // CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());
    // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //frame.setAlwaysOnTop(true);

    while ((grabframe=grabber.grab()) != null) {
        System.out.println("推流..."+inputFile+"/"+outputFile);
        // frame.showImage(grabframe);

        grabbedImage = converter.convert(grabframe);
        Frame rotatedFrame = converter.convert(grabbedImage);

        if (startTime == 0) {
            startTime = System.currentTimeMillis();
        }
        recorder.setTimestamp(1000 * (System.currentTimeMillis() - startTime));//时间戳

        if(rotatedFrame!=null &&  rotatedFrame.imageHeight > 0 && rotatedFrame.imageWidth > 0){
            recorder.record(rotatedFrame);
        }

        //Thread.sleep(2000);//切换成下一个
    }
    // frame.dispose();
   /* recorder.stop();
    recorder.release();
    grabber.stop();
    System.exit(2);*/
    System.out.println("完成了读流的方法");

}

本机边浏览边录制

以下是大神的推流器实现,参考:https://blog.csdn.net/eguid_1/article/details/52678775

本功能采用按帧录制/推流,通过关闭播放窗口停止视频录制/推流

注:长时间运行该代码会导致内存溢出的原因是没有及时释放IplImage资源(由于javacv是jni方式调用C,部分对象需要手动释放资源,以防止内存溢出错误)

/**
     * 按帧录制本机摄像头视频(边预览边录制,停止预览即停止录制)

      我的环境中是录制报警视频到了本地,但是看到这个感觉应该是录制到服务器上的。
     * 
     * @author eguid
     * @param outputFile -录制的文件路径,也可以是rtsp或者rtmp等流媒体服务器发布地址
     * @param frameRate - 视频帧率
     * @throws Exception
     * @throws InterruptedException
     * @throws org.bytedeco.javacv.FrameRecorder.Exception
     */
    public static void recordCamera(String outputFile, double frameRate)
            throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {
        Loader.load(opencv_objdetect.class);
        FrameGrabber grabber = FrameGrabber.createDefault(0);//本机摄像头默认0,这里使用javacv的抓取器,至于使用的是ffmpeg还是opencv,请自行查看源码
        grabber.start();//开启抓取器
 
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();//转换器
        IplImage grabbedImage = converter.convert(grabber.grab());//抓取一帧视频并将其转换为图像,至于用这个图像用来做什么?加水印,人脸识别等等自行添加
        int width = grabbedImage.width();
        int height = grabbedImage.height();
    
        FrameRecorder recorder = FrameRecorder.createDefault(outputFile, width, height);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264,编码
        recorder.setFormat("flv");//封装格式,如果是推送到rtmp就必须是flv封装格式
        recorder.setFrameRate(frameRate);
        
        recorder.start();//开启录制器
        long startTime=0;
        long videoTS=0;
        CanvasFrame frame = new CanvasFrame("camera", CanvasFrame.getDefaultGamma() / grabber.getGamma());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setAlwaysOnTop(true);
        Frame rotatedFrame=converter.convert(grabbedImage);//不知道为什么这里不做转换就不能推到rtmp
        while (frame.isVisible() && (grabbedImage = converter.convert(grabber.grab())) != null) {
            rotatedFrame = converter.convert(grabbedImage);
            frame.showImage(rotatedFrame);
            if (startTime == 0) {
                startTime = System.currentTimeMillis();
            }
            videoTS = 1000 * (System.currentTimeMillis() - startTime);
            recorder.setTimestamp(videoTS);
            recorder.record(rotatedFrame);
            Thread.sleep(40);
        }
        frame.dispose();
        recorder.stop();
        recorder.release();
        grabber.stop();
    
    }

总的来说,我们已经实现了基本的推流器功能,那么需要注意的就是转换那里,不清楚为什么不做转换就不能推送到rtmp流媒体服务器,如果哪位有更好的方案希望可以联系博主,感谢!

测试录制功能和推流功能--本机的推流到nginx和本机的录制到本机

public static void main(String[] args) throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {
        recordCamera("output.mp4",25);

此处感觉录制视频是可以录到本地也可以录到流媒体服务器上的
    }
public static void main(String[] args) throws Exception, InterruptedException, org.bytedeco.javacv.FrameRecorder.Exception {
        recordCamera("rtmp://192.168.30.21/live/record1",25);

此处感觉目前的推流功能时没有问题的。rtmp://192.168.1.113:1935/live/cal_20190218141704
    }

看到了摄像头窗口就说明已经开始录制,点击右上角关闭按钮即停止录制视频,在录制的时候刷新项目目录发现新生成了一个output.mp4文件,可以正常播放这个视频文件

 

8.收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)  

录制nginx上已经推好的流到一个文件中。

inputFile-该地址可以是网络直播/录播地址,也可以是远程/本地文件路径

outputFile -该地址只能是文件地址,如果使用该方法推送流媒体服务器会报错,原因是没有设置编码格式

本功能采用按帧实现收流器录制功能

/**
     * 按帧录制视频
     * 
     * @param inputFile-该地址可以是网络直播/录播地址,也可以是远程/本地文件路径
     * @param outputFile
     *            -该地址只能是文件地址,如果使用该方法推送流媒体服务器会报错,原因是没有设置编码格式

     * @throws FrameGrabber.Exception
     * @throws FrameRecorder.Exception
     * @throws org.bytedeco.javacv.FrameRecorder.Exception
     */
    public static void frameRecord(String inputFile, String outputFile, int audioChannel)
            throws Exception, org.bytedeco.javacv.FrameRecorder.Exception {
        
            boolean isStart=true;//该变量建议设置为全局控制变量,用于控制录制结束
        // 获取视频源
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
        // 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制)
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, 1280, 720, audioChannel);
        // 开始取视频源
        recordByFrame(grabber, recorder, isStart);
    }

 

private static void recordByFrame(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder, Boolean status)
            throws Exception, org.bytedeco.javacv.FrameRecorder.Exception {
        try {//建议在线程中使用该方法
            grabber.start();
            recorder.start();
            Frame frame = null;
            while (status&& (frame = grabber.grabFrame()) != null) {
                recorder.record(frame);
            }
            recorder.stop();
            grabber.stop();
        } finally {
            if (grabber != null) {
                grabber.stop();
            }
        }
    }

3、测试收流器录制功能

inputFile设置为服务器播放地址,

outputFile设置为本地地址,这里演示.mp4,也可以是flv等其他后缀名

public static void main(String[] args)
            throws FrameRecorder.Exception, FrameGrabber.Exception, InterruptedException {
         String inputFile = "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0";
         // Decodes-encodes
         String outputFile = "recorde.mp4";
         frameRecord(inputFile, outputFile,1);
}
//感觉自己写的录制有点复杂了。

到这里我们已经实现了直播功能的全部基本操作:推流,录制,简单的直播系统和多人视频等已经可以实现了;

9.重点中的重点来了,本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地)

但是我们的系统远不止那么简单,比如监控和专业的摄像头,

需要通过rtsp或者码流的形式才能获取视频流

这时我们需要一个转流器,帮助我们把他们转发到流媒体服务器

实现实时监控/视频查看


以下参考大神的资料加个人实战分析:https://blog.csdn.net/eguid_1/article/details/52680802 


重点,重点,重点,重要的事情说三遍,思路清了,一切就简单了。

未免混淆,另外整理一篇。

 

感觉和我本地写的不太一样,

目前本地需要解决的问题:

1.多个摄像头同时推流;-----线程可设置全部开启或者用时开启;

2.nginx推流是不是一个流媒体服务器只能对同一个摄像头推一次不能同时推,否则会报错,导致流媒体服务器关闭;

3.nginx推流到流媒体服务器后,放到video.js中的视频地址是rtmp地址;

4.实现视频的录制,录制的地址是rtsp还是rtmp,录制是可以直接录制还是服务器录到本地或者服务器(设计nginx推流关闭的问题);

5.如果一直开着会占用资源,但是实时监控必须开着,方便报警时进行视频的录制,可以报警后开启视频的录制功能,

但是有可能录制时已经有视频再推流了,两者会冲突,

所以视频推流时rtsp推流到ngingx-rtmp上,

录制是从媒流体服务器录制到文件中,

vue中的video.js的播放地址是rtmp或者是MP4(nginx已经成功推流的地址)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(20190227最近比较纠结的问题vue的video中视频的播放和nginx-rtmp的推流以及什么时候推流的分析)