Project Address
Https://github.com/979451341/RtmpSave
The main code of this project I came from the Thunder god, it is the thunder god, I have a environment to make an interface can be used code.
This time, the rtmp stream is saved as a local flv file. Because playing the video itself has a lot of technical difficulties, I do not do the side to get rtmp stream playback, this time mainly said how to get rtmp stream.
Talk about the code.
Initializing components and network environments
av_register_all();//Networkavformat_network_init();
Open the rtmp stream, get information about the rtmp stream, and search for the location of the video stream
//Inputif ((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; }
Save some configuration information for rtmp stream in the input environment information
av_dump_format(ifmt_ctx, 0, in_filename, 0);
Get output environment information based on output FLV file name and path
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename); //RTMPif (!ofmt_ctx) { printf( "Could not create output context\n"); ret = AVERROR_UNKNOWN; goto end;}
The output format information of output environment information is saved in OFMT
OFMT = ofmt_ctx->oformat;
Creates a stream of output environment information, copies a stream into the environment information, and configures the encoding of each stream
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; } //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;}
debugging functions
Av_dump_format (ofmt_ctx, 0, Out_filename, 1);
Open the Output URL path
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; }}
Writes the file header to the output environment
//Write file headerret = avformat_write_header(ofmt_ctx, NULL);if (ret < 0) { printf( "Error occurred when opening output URL\n"); goto end;}
Configuring the H264 Encoder
#if USE_H264BSF
avbitstreamfiltercontext* H264BSFC = Av_bitstream_filter_init ("H264_mp4toannexb");
#endif
Start loop read Frame write FLV file
Reading video streaming data for a single frame rtmp stream
ret = av_read_frame(ifmt_ctx, &pkt); if (ret < 0) break;
Calculates the associated display frame time of the output data corresponding to this frame input rtmp stream data, the decoding frame time DTS, the distance from the previous frame to the next frame playback time gap duration
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);
Converting one frame of output data according to H264 encoding format
#if USE_H264BSF
Av_bitstream_filter_filter (H264BSFC, In_stream->codec, NULL, &pkt.data, &pkt.size, Pkt.data, pkt.size, 0);
#endif
Writes this frame output data to the FLV file and then releases the frame data
ret = av_interleaved_write_frame(ofmt_ctx, &pkt); if (ret < 0) { printf( "Error muxing packet\n"); break; } av_free_packet(&pkt);
Turning off the H264 encoder
#if USE_H264BSF
Av_bitstream_filter_close (H264BSFC);
#endif
Releasing the input and output environment
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;}
Talk about the use of the app
The click button will be able to click on it will be the word will become started, so he saved the rtmp stream file, after a two minutes to the corresponding path to see it can be
Android Audio Video In depth 17 FFmpeg get rtmp stream saved as flv (with source download)