windows平臺簡易直播系統搭建

    最近作直播系統的朋友不少,正好前端時間也在作這一塊,寫片文章分享下開發心得,覺得後用。前端

直播系統我將它分爲前堆推流,後臺服務,客戶端播放三大部分。前端推流基於ffmpeg,後臺服務linux

使用crtmp服務,播放端可使用JWPlayer(網頁端播放),也能夠是CGplayer。windows

一.前端推流服務器

    推流能夠採用命令: 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推流前面有文章介紹過,負載均衡

這裏將主要的幾個方法介紹下,文章後面會給出完成的工程包。less

      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 = 0;
     ret  = avformat_alloc_output_context2(&outputContext, nullptr, "flv", fileName);
    if(ret < 0)
    {
        goto Error;
    }
    ret = avio_open2(&outputContext->pb, fileName, AVIO_FLAG_READ_WRITE,nullptr, nullptr);    
    if(ret < 0)
    {
        goto Error;
    }
    for(int i = 0; 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 < 0)
        {
            goto Error;
        }

    }
     ret = avformat_write_header(outputContext, nullptr);
    if(ret < 0)
    {
        goto Error;
    }
    return ret ;
Error:
    if(outputContext)
    {
        for(int i = 0; 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

相關文章
相關標籤/搜索