ffmpeg,rtmpdump和nginx rtmp实现录屏,直播和录制

公司最近在做视频直播的项目,我这里分配到对直播的视频进行录制,录制的方式是通过rtmpdump对rtmp的视频流进行录制

前置的知识

  • ffmpeg: 用于实现把录屏工具发出的视频和音频流,转换成我们需要的格式,然后发送到rtmp中转服务器上。
  • rtmpdump: 用于实现视频的录制,从rtmp的中转服务器接受到视频流,并把视频流保存成flv文件
  • nginx-rtmp-module: 用户rtmp中转服务,虽然他可以做很多功能,但是我这里只是使用了这一个
  • screen capture: windows下的开源屏幕录制工具

首先,我们安装ffmpeg, rtmpdump和nginx-rtmp-module:

这里我使用的ffmpegrtmpdump都是windows版的,虽然和linux下的有所区别,但是在这里并没有使用到这些区别。

nginx是在windows下的虚拟机中的linux下编译的,因为windows编译这玩意是在太麻烦了,我实在不想编译第二次。

ffmpeg 的简单使用

首先我们需要查看以下我们的自己上的设备信息,在安装了screen capture recorder之后就可以使用下面的命令:

ffmpeg -list_devices true -f dshow -i dummy

输出如下结果:

ffmpeg version N-63013-g4cdea92 Copyright (c) 2000-2014 the FFmpeg developers
  built on May  6 2014 22:09:20 with gcc 4.8.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-decklink --enable-zlib
  libavutil      52. 81.100 / 52. 81.100
  libavcodec     55. 60.103 / 55. 60.103
  libavformat    55. 37.102 / 55. 37.102
  libavdevice    55. 13.101 / 55. 13.101
  libavfilter     4.  5.100 /  4.  5.100
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 18.100 /  0. 18.100
  libpostproc    52.  3.100 / 52.  3.100
[dshow @ 00000000029f0e20] DirectShow video devices
[dshow @ 00000000029f0e20]  "screen-capture-recorder"
[dshow @ 00000000029f0e20] DirectShow audio devices
[dshow @ 00000000029f0e20]  "FrontMic (Realtek High Definiti"
[dshow @ 00000000029f0e20]  "virtual-audio-capturer"
[dshow @ 00000000029f0e20]  "Realtek Digital Input (Realtek "
dummy: Immediate exit requested

DirectShow video devices下面的是视频设备,DirectShow audio devices是音频设备,ffmpeg录制就需要从这些设备上得到视频和音频的流.

下面我们看以下ffmpeg如果从这些设备中录制视频。

ffmpeg -f dshow -i video="screen-capture-recorder":audio="FrontMic (Realtek High Definiti"  test.avi

这杨就可以把录屏和通过麦克风说话的声音都录下来,保存成avii,当然这里也可以使用更加丰富的参数来调整视频,使视频更清醒,声音也更响亮,不过这些都不在本文的讨论范围,所以就不在这里多少,有兴趣的华可以去http://ffmpeg.org/documentation.html上详细的查看。

当然我们是要使用rtmp协议的,所以这里就需要把视频流发送到rtmp服务端去,如下命令:

ffmpeg -f dshow -i video="screen-capture-recorder":audio="FrontMic (Realtek High Definiti"  -f flv rtmp://192.168.56.101/live/test

这里只说明一点,如果是发送到rtmp协议的话是需要加上-f flv这个参数的,如果不加会报错,这样就算是把录制的视频流发送到了rtmp服务端,当然我这里的nginx服务器要配置好并且启动了,否则还是会报错的。

nginx rtmp module

安装

在编译安装模块的时候需要说明一点,如果在 configure的时候出现了openssl的错误,请安装libssl-dev.

ubuntu下: sudo apt-get install libssl-dev

./configure --prefix=/usr/local/rtmp-nginx --without-http_rewrite_module
make
make install

配置

下面是我的配置:

rtmp {
    server {
        listen 1935;

        chunk_size 4096;

        application live {
            live on;
        }
    }
}
http {
    server {
        listen      8080;

        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root stat;
        }

        location / {
            root /publisher;
        }
    }
}

我们只需要加入一个关于rtmp协议的块和在http协议下加入一个server块,用来配置统计星系等,这就是最简单的配置,这样已经快而已完成我们例子中的功能,如果需要更详细的,请查看NGINX-based Media Streaming Server

RTMPDump

RTMPDump 是一位匈牙利大神在Adobe未公开RTMP协议的条件下,写出了针对RTMP协议的客户端程序。

在这里rtmpdump的使用是很简单的,当然rtmpdump其实也是有一些问题的,我们先来看看如果使用rtmpdump录制视频流

使用

rtmpdump -v -m 0 -r rtmp://192.168.56.101/live/test -o test.flv

上面的命令就是录制rtmp协议的视频流的命令,下面简单说明一下:

  • -v:是说明视频流是一个直播流
  • -m:是超时时间,0表示不超时
  • -r:表示rtmp的url

rtmpdump的使用就是如此的简单

问题

我在实际的使用过程中遇到了一个疑问,就是当视频的发送端崩溃或者死机,造成视频流中断,再次发送的时候会发送一个新的视频流,但是rtmpdump无法分辨这个新视频流,他会把这个视频流继续添加在文件后面,保存成一个文件而不是一个新的视频文件。相反对于网络中断而视频的发送端没有中断这种问题是可以处理的,不过中间可能会出现画面定在网络中断的那个时间点上,知道网络再次恢复。

不过这个问题是可以通过程序的方式解决的,在python的库中有一个flvlib的库可以处理这类问题,请看下面的代码:

def split_flv(f):
    if isinstance(f, str):
        f = open(f, ‘rb‘)
    flv = tags.FLV(f)
    path, ext = os.path.splitext(f.name)
    output_template = path + "_%d" + ext
    input_flv = open(f.name, ‘rb‘)
    output_flv = None
    split_index = 0;
    filelist = []
    for tag in flv.iter_tags():
        if isinstance(tag, tags.ScriptTag) and tag.timestamp == 0:
            if output_flv:
                output_flv.close()
            output_flv = open(output_template % split_index, ‘wb‘)
            filelist.append(output_flv.name)
            split_index += 1
            output_flv.write(tags.create_flv_header(flv.has_audio, flv.has_video))
            output_flv.write(tags.create_script_tag(‘onMetaData‘, tag.variable, tag.timestamp))
        elif isinstance(tag, tags.VideoTag):
            input_flv.seek(tag.offset + 11)
            data = input_flv.read(tag.size)
            newtag = tags.create_flv_tag(9, data, tag.timestamp)
            output_flv.write(newtag)
        elif isinstance(tag, tags.AudioTag):
            input_flv.seek(tag.offset + 11)
            data = input_flv.read(tag.size)
            newtag = tags.create_flv_tag(8, data, tag.timestamp)
            output_flv.write(newtag)
    output_flv.close()
    input_flv.close()
    return filelist

def concat_flv(filelist, src_file):
    tempf = tempfile.TemporaryFile(‘w+b‘, delete=False)
    tempf.writelines(["file ‘%s‘\n" % f for f in filelist])
    tempf.close()
    curdir = os.path.dirname(__file__)
    cmd = ‘ffmpeg‘
    if platform.system() == ‘Windows‘:
        cmd = ‘"‘ + os.path.join(curdir, ‘rtmpdump/ffmpeg.exe‘) + ‘"‘
    src_file_name, src_file_ext = os.path.splitext(src_file)
    output_file = src_file_name + "_concat" + src_file_ext
    cmd += ‘ -f concat -i ‘ + tempf.name + ‘ -y -c copy ‘ + output_file
    p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output = p.communicate()
    logger.info(output[0])
    return (output_file, None)

这两段代码就是先把视频分割开,然后在连接到一起生成一个新文件。

总结

这是我解决直播的一个测试方案,因为公司的直播系统还没有起来,所以我采用了这样一中思路模拟直播测试我的录制系统。

转自http://www.cnblogs.com/fx2008/p/4226820.html

时间: 2024-10-23 01:24:25

ffmpeg,rtmpdump和nginx rtmp实现录屏,直播和录制的相关文章

Android实现录屏直播(一)ScreenRecorder的简单分析

应项目需求瞄准了Bilibili的录屏直播功能,基本就仿着做一个吧.研究后发现Bilibili是使用的MediaProjection 与 VirtualDisplay结合实现的,需要 Android 5.0 Lollipop API 21以上的系统才能使用. 其实官方提供的android-ScreenCapture这个Sample中已经有了MediaRecorder的实现与使用方式,还有使用MediaRecorder实现的录制屏幕到本地文件的Demo,从中我们都能了解这些API的使用. 而如果需

游戏录屏直播的图文教程(基于云直播平台)

原创教程 ( 转载请注明出处 ) 2017-6-26,今天来做一下是电脑游戏桌面录屏直播的教程,就是把桌面的游戏直播出去,加上话筒做讲解.最终实现在电脑.手机.微信中都可以观看到游戏的直播和讲解画面. 提示:1. 本教程说的是游戏录屏直播的图文教程(基于云直播平台,不是基于自建流媒体直播平台) 2. 若要基于自建的流媒体平台,可以用OBS之类的软件来实现,OBS取流发送到自建平台上,实现直播. STEP1 . 硬件准备及设备连接 场景说明: 1.用户做一场电脑游戏桌面直播,实现PC端.手机端(A

iphone怎么录屏 苹果屏幕录制怎么操作

iphone怎么录屏呢?相信很多想要录屏的小伙伴,会想到这个问题,因为苹果手机自带Airplay镜像,所以录屏投屏就简单多了,只要借助第三方工具就可以了,下面详细步骤,一起看看吧! 使用工具: 电脑.苹果手机迅捷苹果录屏精灵 方法/步骤: 1.第一步,这是一个PC端的软件,所以只需要在电脑上下载安装"迅捷苹果录屏精灵"就可以,成功安装之后,打开此软件,可以先登录(验证码或者快捷方式):? 2.第二步,把手机和电脑连接到同一个网络,这是很重要的一步. ? 3.?第三步,投屏的过程中想要进

Bandicam(班迪录屏)高清视频录制工具

Bandicam(班迪录屏)简单好用的录屏幕,录游戏,录视频的功能强大的屏幕录像软件,比起其他软件其性能更加卓越. 与其他软件相比,用Bandicam录制的视频大小更小, 不仅保证原文件的质量. 原文地址:https://www.cnblogs.com/dayuzhishi/p/10658251.html

FFmpeg获取DirectShow设备数据(摄像头,录屏)

这两天研究了FFmpeg获取DirectShow设备数据的方法,在此简单记录一下以作备忘.本文所述的方法主要是对应Windows平台的. 1.       列设备 ffmpeg -list_devices true -f dshow -i dummy 命令执行后输出的结果如下(注:中文的设备会出现乱码的情况).列表显示设备的名称很重要,输入的时候都是使用"-f dshow -i video="{设备名}""的方式. 我自己的机器上列出了以下设备: [dshow @0

使用ffmpeg将录屏文件转换成gif

一.使用华为nova3 内置录屏软件录屏 1.下拉屏幕上方. 2.选择编辑按钮. 3.点击"屏幕录制". 4.倒计时3-2-1. 5.开始录制. 6.录制完毕时用食指以及中指关节敲打手机屏幕,录制好的文件在"图库"-"截屏录屏"中 二.使用ffmpeg将录制好的macrodroidluping.mp4转换成a.gif格式文件. 1.下载ffmpeg,选择 4.02版本-64bit-static 2.安装ffmpeg,安装在d:\ffmpeg 3.

转:Nginx RTMP 功能研究

看点: 1.    Nginx 配置信息与使用.  (支持 rtmp与HLS配置) 2.    有ffmpeg 编译与使用,    命令行方式来测试验证客户端使用. 转自:http://blog.csdn.net/cccallen/article/details/8440191 Nginx-RTMP功能调研 1. RTMP协议介绍...2 2.RTMP server.3 2.1当前的流媒体server.3 2.2Wowza功能...3 3.Nginx-based RTMP server.5 3.

WPF 录屏软件研发心得及思路分享

最近由于工程需要开始研发基于Windows的自动录屏软件,很多细节很多功能需要处理,毕竟一个完美的录屏软件不是你随随便便就可以写出来的.首先参考了大部分的录屏软件,在研发的过程中遇到了很多的问题:比如-视频加载.麦克风加载.麦克风音量调节.视频播放进度控.视频音量控制.等等很多细节部分都需要好好规划才能开始做.录屏采用的是视频帧的思维逻辑进行编写的. 目前已经基本上成型,基于WPF采用了Model - View框架进行动态加载,每个线程与线程之间采用Async异步执行,并使用线程等待:录屏基本功

用ffmpeg推流到nginx

用ffmpeg推流到nginx [1]第一个是推到了上面配置的live节点上:[RTMP模块] ffmpeg -i /data/recorded_flvs/1028_test8-1475221725.flv -c:v libx264 -b:v 500k -c:a libfdk_aac -b:a 64k -f flv rtmp://120.26.206.180/live/strea123.flv 说明:红色为需要推送的文件,绿色为RTMP流, 运行成功界面: [2]第二个推送到hls上: ffmp