Simple-RTMP-Server 伺服器測試
- 伺服器映象獲取
github原始碼地址
git clone https://github.com/winlinvip/simple-rtmp-server.git - 編譯系統
./configure –disable-all –with-ssl –with-hls –with-nginx –with-ffmpeg –with-transcode
make
make install
安裝命令會將SRS預設安裝到/usr/local/srs中,可以在configure時指定其他目錄,譬如./configure –prefix=pwd/_release 可以安裝到當前的_release目錄 建立啟動服務
3.1 建立軟連線
sudo ln -sf /usr/local/srs/etc/init.d/srs /etc/init.d/srs
備註:若SRS安裝到其他目錄,將/usr/local/srs替換成其他目錄。
3.2 新增服務
sudo /sbin/chkconfig –add srs
4.3 使用init.d指令碼管理SRS
檢視SRS狀態:
/etc/init.d/srs status
啟動SRS:
/etc/init.d/srs start
停止SRS:
/etc/init.d/srs stop
重啟SRS:
/etc/init.d/srs restart
Reload SRS:
/etc/init.d/srs reload伺服器開放1935埠
- FFmpeg推流
5.1推流本地flv檔案
ffmpeg -re -i /Users/sample.flv -vcodec libx264 -acodec aac -f flv rtmp://阿里雲伺服器公網ip:1935/rtmplive/home
5.2程式碼推流
#include <iostream>
#include <stdio.h>
extern "C"
{
#include "libavformat/avformat.h"
#include "libavutil/mathematics.h"
#include "libavutil/time.h"
}
int main(int argc, char* argv[])
{
AVOutputFormat *ofmt = NULL;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVPacket pkt;
const char *in_filename, *out_filename;
int ret, i;
int videoindex=-1;
int frame_index=0;
int64_t start_time=0;
in_filename = "/Users/stellazhou/Documents/音視訊測試檔案/sample.flv";
out_filename = "rtmp://阿里雲伺服器公網ip/live/livestream";
av_register_all();
avformat_network_init();
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
printf( "Could not open input file.");
goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
printf( "Failed to retrieve input stream information");
goto end;
}
for(i=0; i<ifmt_ctx->nb_streams; i++)
if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
videoindex=i;
break;
}
av_dump_format(ifmt_ctx, 0, in_filename, 0);
//輸出(Output)
avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_filename); //RTMP
if (!ofmt_ctx) {
printf( "Could not create output context\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ofmt = ofmt_ctx->oformat;
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
//根據輸入流建立輸出流(Create output AVStream according to input AVStream)
AVStream *in_stream = ifmt_ctx->streams[i];
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
if (!out_stream) {
printf( "Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
//複製AVCodecContext的設定(Copy the settings of AVCodecContext)
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
if (ret < 0) {
printf( "Failed to copy context from input to output stream codec context\n");
goto end;
}
out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
//Dump Format------------------
av_dump_format(ofmt_ctx, 0, out_filename, 1);
//開啟輸出URL(Open output URL)
if (!(ofmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
printf( "Could not open output URL '%s'", out_filename);
goto end;
}
}
//寫檔案頭(Write file header)
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
printf( "Error occurred when opening output URL\n");
goto end;
}
start_time=av_gettime();
while (1) {
AVStream *in_stream, *out_stream;
//獲取一個AVPacket(Get an AVPacket)
ret = av_read_frame(ifmt_ctx, &pkt);
if (ret < 0)
break;
//FIX:No PTS (Example: Raw H.264)
//Simple Write PTS
if(pkt.pts==AV_NOPTS_VALUE){
//Write PTS
AVRational time_base1=ifmt_ctx->streams[videoindex]->time_base;
//Duration between 2 frames (us)
int64_t calc_duration=(double)AV_TIME_BASE/av_q2d(ifmt_ctx->streams[videoindex]->r_frame_rate);
//Parameters
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
pkt.dts=pkt.pts;
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
}
//Important:Delay
if(pkt.stream_index==videoindex){
AVRational time_base=ifmt_ctx->streams[videoindex]->time_base;
AVRational time_base_q={1,AV_TIME_BASE};
int64_t pts_time = av_rescale_q(pkt.dts, time_base, time_base_q);
int64_t now_time = av_gettime() - start_time;
if (pts_time > now_time)
av_usleep(pts_time - now_time);
}
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
/* copy packet */
//轉換PTS/DTS(Convert PTS/DTS)
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
//Print to Screen
if(pkt.stream_index==videoindex){
printf("Send %8d video frames to output URL\n",frame_index);
frame_index++;
}
//ret = av_write_frame(ofmt_ctx, &pkt);
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
if (ret < 0) {
printf( "Error muxing packet\n");
break;
}
av_free_packet(&pkt);
}
//寫檔案尾(Write file trailer)
av_write_trailer(ofmt_ctx);
end:
avformat_close_input(&ifmt_ctx);
/* close output */
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_close(ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
if (ret < 0 && ret != AVERROR_EOF) {
printf( "Error occurred.\n");
return -1;
}
return 0;
}
- 用VLC播放rtmp://阿里雲伺服器公網ip/live/livestream
相關文章
- Simple-RTMP-Server 伺服器搭建Server伺服器
- 如何測試伺服器伺服器
- [SRS流媒體]RTMP/HLS 直播伺服器simple-rtmp-server安裝伺服器Server
- 軟體測試中伺服器穩定性測試方法伺服器
- 伺服器網路測試伺服器
- 伺服器的效能測試伺服器
- 如何測試伺服器效能?伺服器
- web伺服器效能測試Web伺服器
- 【伺服器】當我們對伺服器進行測試,我們測試什麼?伺服器
- 如何測試伺服器的速度伺服器
- 伺服器穩定性測試方法伺服器
- 伺服器的速度如何測試伺服器
- 伺服器如何測試穩定性伺服器
- WebStorm配置本地測試伺服器WebORM伺服器
- 軟體測試中伺服器穩定性測試幾種方法伺服器
- 測試測試測試測試測試測試
- 如何使用siege測試伺服器效能伺服器
- 伺服器網路測試的方法伺服器
- MQTT 伺服器安全性測試MQQT伺服器
- 如何測試伺服器的訪問速度伺服器
- Linux伺服器效能壓力測試Linux伺服器
- 頁遊伺服器壓力測試方案伺服器
- 伺服器效能測試典型工具介紹伺服器
- MibBrowser測試伺服器告警上報功能伺服器
- 多執行緒伺服器壓力測試執行緒伺服器
- 怎麼測試伺服器穩不穩定伺服器
- 雲伺服器nginx和webman壓力測試伺服器NginxWeb
- 伺服器網路測試的幾種方法伺服器
- 測試伺服器頻寬的幾種方法伺服器
- 怎麼測試伺服器的訪問速度伺服器
- .net core grpc單元測試 - 伺服器端RPC伺服器
- 使用queryperf對DNS伺服器作壓力測試DNS伺服器
- 伺服器滲透測試之攻擊漏洞方法伺服器
- 伺服器頻寬測試的意義與方法伺服器
- 新手如何測試伺服器的速度?有哪些方法伺服器
- 伺服器硬碟讀寫大檔案速度測試伺服器硬碟
- 建立 測試環境 + 配置伺服器ssl證書伺服器
- 【轉】 Ubuntu samba伺服器搭建及測試--不錯UbuntuSamba伺服器