windows平台简易直播系统搭建
最近做直播系统的朋友很多,正好前端时间也在做这一块,写片文章分享下开发心得,以为后用。
直播系统我将它分为前堆推流,后台服务,客户端播放三大部分。前端推流基于ffmpeg,后台服务
使用crtmp服务,播放端可以使用JWPlayer(网页端播放),也可以是CGplayer。
一.前端推流
推流可以采用命令: ffmpeg -i input -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/cgstream0
input 可以是实时流,也可以是文件,如果是文件 需要加上-re。运用中需要将127.0.0.1换成rtmp所在机器的ip地址。
用命令推流时间戳信息不能任意修改,想要达到一个满意的结果还是要用代码实现。rtmp推流前面有文章介绍过,
这里将主要的几个方法介绍下,文章后面会给出完成的工程包。
ffmpeg推流 如果不需要重写编码(视频源已经是编码好的数据),推流的过程比较简单就是一个demux和remux过程。
主要方法代码如下:
1.打开视频流,filename可以文件名称也可以是实时流url.
int OpenInput(char *fileName)
{
AVDictionary* options = nullptr;
context = avformat_alloc_context();
cout << "Begin Open file Input " << endl;
lastTime = av_gettime();
context->interrupt_callback.callback = interrupt_cb;
int ret = avformat_open_input(&context, fileName, nullptr,&options);
if(ret < 0)
{
return ret;
}
ret = avformat_find_stream_info(context,nullptr);
return ret;
}
2.创建输出上下文以及输出流,输出流的格式需要设置成flv
int OpenOutput(char *fileName)
{
int ret = ;
ret = avformat_alloc_output_context2(&outputContext, nullptr, "flv", fileName);
if(ret < )
{
goto Error;
}
ret = avio_open2(&outputContext->pb, fileName, AVIO_FLAG_READ_WRITE,nullptr, nullptr);
if(ret < )
{
goto Error;
}
for(int i = ; i < context->nb_streams; i++)
{
AVStream * stream = avformat_new_stream(outputContext, context->streams[i]->codec->codec);
ret = avcodec_copy_context(stream->codec, context->streams[i]->codec); if(ret < )
{
goto Error;
} }
ret = avformat_write_header(outputContext, nullptr);
if(ret < )
{
goto Error;
}
return ret ;
Error:
if(outputContext)
{
for(int i = ; i < outputContext->nb_streams; i++)
{
avcodec_close(outputContext->streams[i]->codec);
}
avformat_close_input(&outputContext);
}
return ret ;
}
3. 从输入流中读取音视频包
shared_ptr<AVPacket> ReadPacketFormSource()
{
shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))),
[&](AVPacket *p) { av_free_packet(p); av_freep(&p);});
av_init_packet(packet.get());
lastTime = av_gettime();
int ret = av_read_frame(context, packet.get());
if(ret >= 0)
{
return packet;
}
return nullptr;
}
4. 简单示例
int main(int argc,char *argv[])
{
if(argc != 3)
{
std::cout <<" more or less parameters "<<endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
string fileInput= argv[1];
string fileOutput = argv[2];
thread task;
bool streamEof = false;
std::cout <<"input file is:"<< fileInput<< endl;
std::cout <<"output file is:"<< fileOutput << endl;
Init();
if(OpenInput((char *)fileInput.c_str()) < 0)
{
std::cout << "Open file Input failed!" << endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
std::cout <<"OpenInput successful"<<endl;
if(OpenOutput((char *)fileOutput.c_str()) < 0)
{
std::cout << "Open file Output failed!" << endl;
this_thread::sleep_for(chrono::seconds(1000));
return 0;
}
std::cout <<"OpenOutput successful"<<endl;
int count = 0;
auto timebase = av_q2d(context->streams[0]->time_base);
int ret = 0;
while(true)
{
auto packet = ReadPacketFormSource(); if(packet)
{
ret = av_write_frame(outputContext,packet.get());
}
if(ret < 0 )
{
break;
}
}
}
fileOutput 可以赋值为rtmp://127.0.0.1/live/cgstream0,表示视频流将要推送到本地的rtmp服务,默认端口是1935.
二. 服务端
服务端可以选择crtmpserver,crtmpserver开源,在windows平台以及linux平台下都可以运行,很多朋友总会问crtmpserver效率
如何,有人质疑:crtmpserver是一个单线程的select模型,能否满足高并发的性能要求。质疑是有理的,有段时间我打算将crtmpserver改成
并行结构,后来我还是放弃了,因为很多情况下用不到,还是等需求来了再改。大部分情况下,瓶颈并不在crtmpserver能并发多少路,而在网络
带宽能支持多少路音视频流。随着人们对视频质量要求的提高,基本上视频的分辨率都是高清(1080p),码率基本会在4M以上。试想如果服务器
网卡选择千兆网卡,单个网卡最多也就支持两百多路。一般来讲,服务器的cpu配置会比普通电脑高很多,支持几百路并发是不会出现性能问题。当然,
如果追求最低的配置实现最高的并发也许crtmpserver不是最好的选择,但项目讲究实用,很多场合下足以满足需求。说到这里,肯定有人会问,如果并
发访问的命令上千上万怎么办?答案是负载均衡。
三. 播放端
如果在网页上播放(IE),可以选择JwPlayer,如果用插件的也是可以。Android端播放器如果底层基于ffmpeg,也可以播放CrtmpServer
转发的音视频流(ffmpeg需要引入librtmp库),IOS系统 同理。播放的url是rtmp://127.0.0.1/live/cgstream0。
如果需要技术交流可加QQ 350197870,或加群流媒体/Ffmpeg/音视频 127903734讨论,CrtmpServer以及JwPlayer可以在群里
直接下载,推流部分的源码过两天,也会上传上来。
四. 如何搭建
说了半天,有些新手朋友可能还不知道如何动手搭建一个简单的直播系统,怎么推流,又如何播放,下面我一步步介绍.
1.首先 下载CrtmpServer服务(可以直接从群里下载),运行双击文件夹下的crtmpserver.exe,如果没有闪退,说明运行成功.
2.下载ffmpeg.exe (可以从群里直接下载),在命令行执行 ffmpeg -i input -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/cgstream0
127.0.0.1改成crtmpserver.exe所在服务器的地址.如果你在linux下推流,需要linux版本的ffmpeg。cgstream0可以根据需要任意修改。在 windows平台下如果推流成功ffmpeg会一直打印信息,出错也会有相应的提示。
3.播放:播放可以用ffplayer.exe(可以从群里下载,这个工具对rtmp流支持不是很好 ,播放的地址是rtmp://127.0.0.1/live/cgstream0 live=1),JwPlayer(用法前面有文章介绍), 还可以用CGPlayer播放器
(这是本人写的不检查时间戳的rtmp播放器 播放的地址是rtmp://127.0.0.1/live/cgstream0 live=1)。过两天会将下载地址粘贴上来。
如需交流,可以加QQ群1038388075,766718184,或者QQ:350197870
视频教程 播放地址: http://www.iqiyi.com/u/1426749687
视频下载地址:http://www.chungen90.com/?news_3/
Demo下载地址: http://www.chungen90.com/?news_2
windows平台简易直播系统搭建的更多相关文章
- H264音视频直播系统 服务器端+客户端源码 可用于直播系统搭建
RTP协议实现直播系统搭建,采用H.264和AAC编码,码率极低,同时有较高的视频清晰度和音频音质,可用于视频聊天.视频会议.摄像头监控等多种应用场景. 直播系统搭建发布端,选择视频和音频设备,指定服 ...
- Windows平台分布式网站系统应用(转)
概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...
- Windows平台上使用Github搭建Git服务器的图文教程
Git没有客户端服务器端的概念,但是要共享Git仓库,就需要用到通信协议,例如SSH协议(FTP , HTTPS , SFTP等协议也能实现Git共享,此文档不讨论),但是SSH有客户端服务器端,所以 ...
- 在Windows平台下使用Gitblit搭建Git服务器图文解说
Windows平台下Git服务器搭建 一.java环境变量的设置 下载jdk并配置jdk的环境变量,JAVA_HOME,CLASSPATH以及PATH,最后在DOS窗口输入java -version检 ...
- Windows下本机简易监控系统搭建(Telegraf+Influxdb+Grafana)
一.文件准备 1.1 文件名称 telegraf-1.2.1_windows_amd64.zip influxdb-1.2.2_windows_amd64.zip grafana-4.2.0.wind ...
- Windows下本机简易监控系统搭建(Telegraf+Influxdb+Grafana)--转
原文地址:http://www.cnblogs.com/liugh/p/6683488.html 一.文件准备 1.1 文件名称 telegraf-1.2.1_windows_amd64.zip in ...
- Telegraf+Influxdb+Grafana(Windows下本机简易监控系统搭建)
1.文件名称 telegraf-1.5.0_windows_amd64.zip influxdb-1.4.2_windows_amd64.zip grafana-4.6.3.windows-x64.z ...
- [Flutter] Windows平台Flutter开发环境搭建(Andorid Studio)
前两天网友在群里说起了Flutter,就了解了一下,在手机上跑了它的demo,直接就被打动了. 虽然网上有很多教程,但真正开始的时候,还是会碰到很多坑.下面详细的讲解Flutter + Android ...
- Nginx-rtmp+ FFmpeg +Docker + vue.js 直播系统搭建
思路(如图): 1,开启推流服务器(这里我的Nginx-rtmp服务器搭建成功) 进入docker 开启推流服务器 docker run -it -p 1935:1935 -p 8000:80 -- ...
随机推荐
- [git 学习篇] git checkout 撤销修改
git status 查看当前创库情况 liuzhipeng@exdroid43:~/pad/pad-test$ git status 位于分支 master 您的分支与上游分支 'origin/ma ...
- 近期JS心得
child和tags都是[{id:1,value:'a'}]的格式,当点击一级标签,要看二级标签是否已经被选中,如果被选中,则清除出去 如果用for循环 再splice的话 当删除掉了一个元素后,数组 ...
- 【Luogu】P3521ROT-Tree Rotations(线段树合并)
题目链接 神奇的线段树合并qwq 不过就思路而言很好想…… 观察到一棵树无论怎么交换两棵左右子树,子树内部的最优逆序对并没影响……决策只影响左右子树之间的逆序对…… 于是线段树合并直接乱搞就好啦 ...
- 算法复习——最小表示法(bzoj2882)
题目: Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到 ...
- 刷题总结——date(ssoj)
题目: 题目背景 SOURCE:NOIP2015-SHY-9 题目描述 小Y和小Z好不容易有机会相见啦,可是邪恶的小H却不想让他们相见.现在有一些城市,城市之间有双向路径相连,有路径相连的城市之间可以 ...
- Date对象在苹果手机下兼容问题的解决方法
Date在不同浏览器中对于传入的时间字符串的格式要求是不一样的.比如在chrome浏览器的控制台中输入以下内容,会得到相应结果: Date.parse('2015-11-11 00:00:00') / ...
- Pebbles(hdu 2167)
题意:给定一个N*N的方格,让你在里面取出一些数使其和最大,要求每一个数不能与其相邻的8个数同时取出. /* 和hdu1565差不多,只不过在更新的时候考虑斜上方的格子对该格子的影响. */ #inc ...
- APUE 学习笔记(三) 文件和目录
1. 文件类型 文件类型信息包含在 struct stat 里的 st_mode 成员 (1)普通文件,unix内核并不区分文本文件和二进制文件 (2)目录文件,这种文件包含了其他文件的名字以及指向这 ...
- javaweb学习总结(十六)——JSP指令(转)
一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: pa ...
- 【NOIP2016后记】
身在浙江,又跪一年 你哪次正式比赛没跪??? 有的人初三联赛一等前途光明,比如衲姐,周驿东 有的人高一联赛一等为时未晚,比如MG,罗爷爷,陈冲 有的人高二联赛一等纵情声色,比如鸟爷爷,小鸡 有的人高三 ...