本文主要參考來自雷霄驊的博客,使用nginx測是RTMP推流。
測試環境: ubuntu + nginx + vlchtml
#include <libavformat/avformat.h> #include <libavutil/mathematics.h> #include <libavutil/time.h>
av_register_all(); avformat_network_init();
//輸入(Input) 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; } int videoindex=-1; 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 //avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", out_filename);//UDP 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);
int avio_open (AVIOContext **s, const char *url, int flags); int avio_open2 (AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary ** options);
這兩個函數的flags參數相似Linux下的open函數,它的Value是:nginx
AVIO_FLAG_READ AVIO_FLAG_WRITE AVIO_FLAG_READ_WRITE
avio_xx 具體函數手冊上很詳細,用法和Linux編程類型,經常使用的函數還有avio_close, avio_read, avio_write
等,更多...
如今,使用avio_open函數打開rtmp地址, 同時寫入文件頭:git
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); } } //寫文件頭(Write file header) ret = avformat_write_header(ofmt_ctx, NULL); if (ret < 0) { printf( "Error occurred when opening output URL\n"); }
ret = av_read_frame(ifmt_ctx, &pkt); ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
av_write_trailer(ofmt_ctx); avio_close(ofmt_ctx->pb);