ffmpeg代码推流rtmp
时间: 2024-03-14 15:41:53 浏览: 147
FFmpeg是一个开源的跨平台音视频处理工具,它提供了丰富的功能和接口,可以用于音视频的编解码、转码、推流等操作。下面是使用FFmpeg进行RTMP推流的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
int main(int argc, char *argv[]) {
AVFormatContext *fmt_ctx = NULL;
AVOutputFormat *out_fmt = NULL;
AVStream *video_stream = NULL;
AVCodecContext *codec_ctx = NULL;
AVCodec *codec = NULL;
AVPacket pkt;
int ret;
// 初始化FFmpeg库
av_register_all();
// 创建输出上下文
ret = avformat_alloc_output_context2(&fmt_ctx, NULL, "flv", "rtmp://your_rtmp_url");
if (ret < 0) {
fprintf(stderr, "Failed to allocate output context: %s\n", av_err2str(ret));
return ret;
}
out_fmt = fmt_ctx->oformat;
// 添加视频流
video_stream = avformat_new_stream(fmt_ctx, NULL);
if (!video_stream) {
fprintf(stderr, "Failed to create video stream\n");
return -1; }
codec_ctx = video_stream->codec;
// 设置编码器参数
codec_ctx->codec_id = out_fmt->video_codec;
codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
codec_ctx->width = 640;
codec_ctx->height = 480;
codec_ctx->bit_rate = 400000;
codec_ctx->gop_size = 10;
codec_ctx->time_base = (AVRational){1, 25};
// 查找编码器
codec = avcodec_find_encoder(codec_ctx->codec_id);
if (!codec) {
fprintf(stderr, "Codec not found\n"); return -1;
}
// 打开编码器
ret = avcodec_open2(codec_ctx, codec, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to open codec: %s\n", av_err2str(ret));
return ret;
}
// 打开输出URL
ret = avio_open(&fmt_ctx->pb, fmt_ctx->url, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Failed to open output URL: %s\n", av_err2str(ret));
return ret;
}
// 写入文件头
ret = avformat_write_header(fmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to write header: %s\n", av_err2str(ret));
return ret;
}
// 初始化视频帧
AVFrame *frame = av_frame_alloc();
frame->format = codec_ctx->pix_fmt;
frame->width = codec_ctx->width;
frame->height = codec_ctx->height;
// 分配视频帧缓冲区
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Failed to allocate frame buffer: %s\n", av_err2str(ret));
return ret;
}
// 编码并推流
int frame_count = 0;
while (frame_count < 100) {
// 生成测试图像
for (int y = 0; y < codec_ctx->height; y++) {
for (int x = 0; x < codec_ctx->width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + frame_count * 3;
}
}
// 设置时间戳
frame->pts = frame_count;
// 发送视频帧
ret = avcodec_send_frame(codec_ctx, frame);
if (ret < 0) {
fprintf(stderr, "Failed to send frame: %s\n", av_err2str(ret));
return ret;
}
// 接收编码后的数据包
while (ret >= 0) {
ret = avcodec_receive_packet(codec_ctx, &pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
fprintf(stderr, "Failed to receive packet: %s\n", av_err2str(ret));
return ret;
}
// 设置流索引和时间戳
pkt.stream_index = video_stream->index;
av_packet_rescale_ts(&pkt, codec_ctx->time_base, video_stream->time_base);
pkt.pos = -1;
// 写入数据包
ret = av_interleaved_write_frame(fmt_ctx, &pkt);
if (ret < 0) {
fprintf(stderr, "Failed to write packet: %s\n", av_err2str(ret));
return ret;
}
av_packet_unref(&pkt);
}
frame_count++;
}
// 写入文件尾
ret = av_write_trailer(fmt_ctx);
if (ret < 0) {
fprintf(stderr, "Failed to write trailer: %s\n", av_err2str(ret));
return ret;
}
// 释放资源
av_frame_free(&frame);
avcodec_close(codec_ctx);
avio_close(fmt_ctx->pb);
avformat_free_context(fmt_ctx);
return 0;
}
```
上述代码使用FFmpeg库进行RTMP推流,首先创建输出上下文,然后添加视频流并设置编码器参数。接下来,打开编码器和输出URL,并写入文件头。然后,初始化视频帧并分配帧缓冲区。在循环中,生成测试图像并发送视频帧,然后接收编码后的数据包并写入。最后,写入文件尾并释放资源。
阅读全文