ffmpeg 推拉流 代码
时间: 2024-02-26 19:50:54 浏览: 37
FFmpeg是一个开源的跨平台音视频处理工具,可以用于音视频的编解码、转码、推拉流等操作。下面是一个简单的示例代码,用于推送和拉取流:
1. 推流代码示例:
```c
#include <stdio.h>
#include <libavformat/avformat.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;
AVFrame *frame = NULL;
AVPacket pkt;
const char *output_url = "rtmp://example.com/live/stream";
av_register_all();
// 初始化输出格式上下文
avformat_alloc_output_context2(&fmt_ctx, NULL, "flv", output_url);
if (!fmt_ctx) {
printf("Failed to allocate output context\n");
return -1;
}
out_fmt = fmt_ctx->oformat;
// 添加视频流
video_stream = avformat_new_stream(fmt_ctx, NULL);
if (!video_stream) {
printf("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 = avcodec_find_encoder(codec_ctx->codec_id);
if (!codec) {
printf("Failed to find encoder\n");
return -1;
}
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
printf("Failed to open encoder\n");
return -1;
}
// 打开输出URL
if (avio_open(&fmt_ctx->pb, output_url, AVIO_FLAG_WRITE) < 0) {
printf("Failed to open output URL\n");
return -1;
}
// 写入文件头
if (avformat_write_header(fmt_ctx, NULL) < 0) {
printf("Failed to write header\n");
return -1;
}
// 初始化帧
frame = av_frame_alloc();
frame->format = codec_ctx->pix_fmt;
frame->width = codec_ctx->width;
frame->height = codec_ctx->height;
// 分配帧数据缓冲区
int ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
printf("Failed to allocate frame buffer\n");
return -1;
}
// 推送视频帧
for (int i = 0; i < 100; i++) {
// 生成测试图像数据
// ...
// 将图像数据填充到帧中
// ...
// 编码帧
// ...
// 将编码后的数据写入输出流
av_interleaved_write_frame(fmt_ctx, &pkt);
av_packet_unref(&pkt);
}
// 写入文件尾
av_write_trailer(fmt_ctx);
// 清理资源
av_frame_free(&frame);
avcodec_close(codec_ctx);
avio_close(fmt_ctx->pb);
avformat_free_context(fmt_ctx);
return 0;
}
```
2. 拉流代码示例:
```c
#include <stdio.h>
#include <libavformat/avformat.h>
int main(int argc, char *argv[]) {
AVFormatContext *fmt_ctx = NULL;
AVCodecContext *codec_ctx = NULL;
AVCodec *codec = NULL;
AVPacket pkt;
AVFrame *frame = NULL;
const char *input_url = "rtmp://example.com/live/stream";
av_register_all();
// 打开输入URL
if (avformat_open_input(&fmt_ctx, input_url, NULL, NULL) != 0) {
printf("Failed to open input URL\n");
return -1;
}
// 获取流信息
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
printf("Failed to find stream info\n");
return -1;
}
// 查找视频流索引
int video_stream_index = -1;
for (int i = 0; i < fmt_ctx->nb_streams; i++) {
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_index = i;
break;
}
}
if (video_stream_index == -1) {
printf("Failed to find video stream\n");
return -1;
}
// 获取视频流解码器参数
codec_ctx = avcodec_alloc_context3(NULL);
if (!codec_ctx) {
printf("Failed to allocate codec context\n");
return -1;
}
if (avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[video_stream_index]->codecpar) < 0) {
printf("Failed to copy codec parameters to context\n");
return -1;
}
// 查找解码器
codec = avcodec_find_decoder(codec_ctx->codec_id);
if (!codec) {
printf("Failed to find decoder\n");
return -1;
}
// 打开解码器
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
printf("Failed to open decoder\n");
return -1;
}
// 初始化帧
frame = av_frame_alloc();
// 读取视频帧
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == video_stream_index) {
// 解码帧
// ...
// 处理解码后的数据
// ...
}
av_packet_unref(&pkt);
}
// 清理资源
av_frame_free(&frame);
avcodec_close(codec_ctx);
avformat_close_input(&fmt_ctx);
return 0;
}
```
这是一个简单的示例代码,用于推送和拉取流。实际使用时,还需要根据具体需求进行参数配置和错误处理。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)