程式碼:使用ffmpeg從網路拉流

來源:互聯網
上載者:User

#include "stdafx.h"


extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
};


#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")


/* 雷霄驊
FIX: H.264 in some container format (FLV, MP4, MKV etc.) need "h264_mp4toannexb" bitstream filter (BSF)
* Add SPS,PPS in front of IDR frame
* Add start code ("0,0,0,1") in front of NALU
H.264 in some container (MPEG2TS) don't need this BSF.
*/


//'1': Use H.264 Bitstream Filter 
#define USE_H264BSF 1


/* 雷霄驊
FIX:AAC in some container format (FLV, MP4, MKV etc.) need "aac_adtstoasc" bitstream filter (BSF)
*/
//'1': Use AAC Bitstream Filter 
#define USE_AACBSF 1


int main(int argc, char* argv[])
{
// Variables Definition


AVFormatContext* ifmt_ctx = NULL; // Format context of input stream
const char* input_filepath = NULL; // File path of input stream

int idx_audio = -1; // index of input audio stream
int idx_video = -1; // index of input video stream


AVStream* pAudioStream = NULL; // Stream structure of input audio stream
AVStream* pVideoStream = NULL; // ... of input video stream


AVFormatContext* ofmt_ctx = NULL; // Format context of output stream
AVStream* pAudioStream_out = NULL; // Output audio stream (AAC)
AVStream* pVideoStream_out = NULL; // Output video stream (H264)
const char* output_filepath = NULL; // File path of output stream

AVPacket ipkt = { 0 }; // 


// Variables Definition end


// Initialize libavformat and register all the muxers, demuxers and *protocols
av_register_all();


// Do global initialization of network components
avformat_network_init();


/* INPUT STREAM */


input_filepath = "rtmp://live.hkstv.hk.lxdns.com/live/hks";


// Open an input stream and read the header. The codecs are not opened.
if (avformat_open_input(&ifmt_ctx, input_filepath, NULL, NULL) < 0)
{
printf("error: avformat_open_input\n");
goto END;
}


// Read packets of a media file to get stream information.
if (avformat_find_stream_info(ifmt_ctx, NULL) < 0)
{
printf("error: avformat_find_stream_info\n");
goto END;
}


// Find the stream in the file.
for (int i = 0; i < ifmt_ctx->nb_streams; i++)
{
// audio stream
if (AVMEDIA_TYPE_AUDIO == ifmt_ctx->streams[i]->codec->codec_type)
{
idx_audio = i;
}
// video stream
else if (AVMEDIA_TYPE_VIDEO == ifmt_ctx->streams[i]->codec->codec_type)
{
idx_video = i;
}
else
{
break;
}
}


if (idx_video < 0 || idx_audio < 0)
{
printf("error: can not find any audio stream or video stream\n");
goto END;
}


// input audio stream and input video stream
pAudioStream = ifmt_ctx->streams[idx_audio];
pVideoStream = ifmt_ctx->streams[idx_video];


/* OUTPUT STREAM */


//output_filepath = "rtmp://127.0.0.1/live/mytest";
output_filepath = "output.flv";


// Allocate an AVFormatContext for an output format.
avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", output_filepath);
if (NULL == ofmt_ctx)
{
printf("error: avformat_alloc_output_context2, output stream\n");
goto END;
}


// Add a new stream to a media file.
pAudioStream_out = avformat_new_stream(ofmt_ctx, NULL);
if (NULL == pAudioStream_out)
{
printf("error: avformat_new_stream, output audio\n");
goto END;
}


pVideoStream_out = avformat_new_stream(ofmt_ctx, NULL);
if (NULL == pVideoStream_out)
{
printf("error: avformat_new_stream, output video\n");
goto END;
}


// Copy the settings of the source AVCodecContext into the destination AVCodecContext.
if (avcodec_copy_context(pAudioStream_out->codec, pAudioStream->codec) < 0)
{
printf("error: avcodec_copy_context, output audio\n");
goto END;
}


if (avcodec_copy_context(pVideoStream_out->codec, pVideoStream->codec) < 0)
{
printf("error: avcodec_copy_context, output video\n");
goto END;
}


// Create and initialize a AVIOContext for accessing the resource.
if (avio_open(&ofmt_ctx->pb, output_filepath, AVIO_FLAG_WRITE) < 0)
{
printf("error: avio_open, output stream\n");
goto END;
}


// Allocate the stream private data and write the stream header to an output media file.
if (avformat_write_header(ofmt_ctx, NULL) < 0)
{
printf("error: avformat_write_header, output stream\n");
goto END;
}


// Print detailed information about the input or output format.
av_dump_format(ifmt_ctx, -1, input_filepath, 0);
av_dump_format(ofmt_ctx, -1, output_filepath, 1);


#if USE_H264BSF
// Create and initialize a bitstream filter context given a bitstream filter name.
AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
#endif


#if USE_AACBSF
AVBitStreamFilterContext* aacbsfc = av_bitstream_filter_init("aac_adtstoasc");
#endif


// Initialize optional fields of a packet with default values.
av_init_packet(&ipkt);
ipkt.data = NULL;
ipkt.size = 0;


while (1)
{
// Return the next frame of a stream.
if (av_read_frame(ifmt_ctx, &ipkt) < 0)
break;


if (ipkt.stream_index == idx_audio)
{
#if USE_AACBSF
// Filter bitstream.
av_bitstream_filter_filter(aacbsfc, pAudioStream->codec, NULL, &ipkt.data, &ipkt.size, ipkt.data, ipkt.size, 0);
#endif
// Write a packet to an output media file ensuring correct interleaving.
if (av_interleaved_write_frame(ofmt_ctx, &ipkt) < 0)
{
printf("error: av_interleaved_write_frame, output audio\n");
break;
}


}
else if (ipkt.stream_index == idx_video)
{
#if USE_H264BSF
av_bitstream_filter_filter(h264bsfc, pVideoStream->codec, NULL, &ipkt.data, &ipkt.size, ipkt.data, ipkt.size, 0);
#endif
if (av_interleaved_write_frame(ofmt_ctx, &ipkt) < 0)
{
printf("error: av_interleaved_write_frame, output video\n");
break;
}
}
else
{
continue;
}


// Free a packet.
av_free_packet(&ipkt);
}


// Write the stream trailer to an output media file and free the file private data.
if (0 != av_write_trailer(ofmt_ctx))
{
printf("error: av_write_trailer\n");
goto END;
}


#if USE_H264BSF
// Release bitstream filter context.
av_bitstream_filter_close(h264bsfc);
#endif


#if USE_AACBSF
av_bitstream_filter_close(aacbsfc);
#endif


END:
// Close an opened input AVFormatContext.Free it and all its contents and set *s to NULL.
avformat_close_input(&ifmt_ctx);

// Close the resource accessed by the AVIOContext s and free it.
if (NULL != ofmt_ctx)
avio_close(ofmt_ctx->pb);

// Free an AVFormatContext and all its streams.
avformat_free_context(ofmt_ctx);


    return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.