ffmpeg rtmp 推流c++示例
时间: 2023-07-03 08:31:28 浏览: 139
以下是一个简单的C++代码示例,用于使用FFmpeg将视频流推送到RTMP服务器:
```c++
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cstring>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
using namespace std;
#define STREAM_URL "rtmp://your_rtmp_server_url"
#define FRAME_RATE 25
int main(int argc, char* argv[]) {
AVFormatContext* pFormatCtx;
AVOutputFormat* pOutputFmt;
AVStream* pStream;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
pOutputFmt = av_guess_format(NULL, STREAM_URL, NULL);
pFormatCtx->oformat = pOutputFmt;
pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
pStream = avformat_new_stream(pFormatCtx, pCodec);
pCodecCtx = avcodec_alloc_context3(pCodec);
pCodecCtx->codec_id = pOutputFmt->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
pCodecCtx->width = 640;
pCodecCtx->height = 480;
pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = FRAME_RATE;
pCodecCtx->bit_rate = 400000;
pCodecCtx->gop_size = 10;
pCodecCtx->max_b_frames = 1;
av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0);
av_opt_set(pCodecCtx->priv_data, "tune", "zerolatency", 0);
avcodec_open2(pCodecCtx, pCodec, NULL);
avcodec_parameters_from_context(pStream->codecpar, pCodecCtx);
avio_open(&pFormatCtx->pb, STREAM_URL, AVIO_FLAG_WRITE);
avformat_write_header(pFormatCtx, NULL);
AVFrame* pFrame = av_frame_alloc();
pFrame->format = pCodecCtx->pix_fmt;
pFrame->width = pCodecCtx->width;
pFrame->height = pCodecCtx->height;
av_image_alloc(pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 32);
SwsContext* pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL);
AVPacket pkt;
int ret;
for (int i = 0; i < 1000; i++) {
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
// 从摄像头获取图像数据,并拷贝到pFrame中
// 这里假设从摄像头获取的图像数据格式为BGR24
// 实际应用中需要根据不同的情况进行修改
// 可以使用OpenCV等库来获取摄像头数据
// 这里只是简单的模拟获取数据的过程
uint8_t* pImgData = new uint8_t[pCodecCtx->width * pCodecCtx->height * 3];
memset(pImgData, 100, pCodecCtx->width * pCodecCtx->height * 3);
memcpy(pFrame->data[0], pImgData, pCodecCtx->width * pCodecCtx->height * 3);
// 转换图像格式
sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrame->data, pFrame->linesize);
pFrame->pts = i;
ret = avcodec_send_frame(pCodecCtx, pFrame);
if (ret < 0) {
cout << "Error sending a frame to the encoder" << endl;
break;
}
while (ret >= 0) {
ret = avcodec_receive_packet(pCodecCtx, &pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
}
else if (ret < 0) {
cout << "Error encoding a frame" << endl;
break;
}
// 设置packet的时间戳和时长
pkt.stream_index = pStream->index;
av_packet_rescale_ts(&pkt, pCodecCtx->time_base, pStream->time_base);
pkt.duration = pCodecCtx->time_base.den / (2 * FRAME_RATE);
// 写入packet到输出流
ret = av_interleaved_write_frame(pFormatCtx, &pkt);
if (ret < 0) {
cout << "Error writing a frame to the output stream" << endl;
break;
}
av_packet_unref(&pkt);
}
delete[] pImgData;
}
av_write_trailer(pFormatCtx);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avcodec_free_context(&pCodecCtx);
avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx);
return 0;
}
```
请注意,这只是一个简单的示例,实际应用中需要根据不同的情况进行修改。例如,从摄像头获取图像数据的方式可能会有所不同。此外,还需要处理错误和异常情况,以确保程序的稳定性和可靠性。
阅读全文