ffmpeg 推流代码
时间: 2023-10-01 15:08:16 浏览: 150
FFmpeg 是一个开源的多媒体转换工具,它可以用来进行音频和视频的转码、解码、编码等多种操作。如果您想使用 FFmpeg 进行推流,可以使用下面的代码:
```
ffmpeg -re -i input.mp4 -c:v libx264 -b:v 500k -r 30 -s 640x360 -c:a aac -b:a 96k -f flv rtmp://your-server-url/live/stream_name
```
上面的代码将一个 MP4 文件(即 `input.mp4`)作为输入,并使用 H.264 视频编码和 AAC 音频编码将其推送到 RTMP 服务器(即 `rtmp://your-server-url/live/stream_name`)。
注意:您需要替换 `your-server-url` 和 `stream_name` 为您自己的服务器地址和直播流名称。
相关问题
ffmpeg 推拉流 代码
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;
}
```
这是一个简单的示例代码,用于推送和拉取流。实际使用时,还需要根据具体需求进行参数配置和错误处理。
qt ffmpeg 推流代码
当使用Qt和FFmpeg进行推流时,你可以使用以下代码示例:
```cpp
#include <QCoreApplication>
#include <QDebug>
#include <QDateTime>
#include <QMutex>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 初始化FFmpeg库
av_register_all();
avformat_network_init();
AVFormatContext *formatContext = nullptr;
AVOutputFormat *outputFormat = nullptr;
AVStream *stream = nullptr;
AVCodec *codec = nullptr;
AVCodecContext *codecContext = nullptr;
AVPacket packet;
// 配置输入视频参数
QString inputFileName = "input.mp4";
AVFormatContext *inputFormatContext = avformat_alloc_context();
if (avformat_open_input(&inputFormatContext, inputFileName.toUtf8().constData(), nullptr, nullptr) < 0) {
qDebug() << "Could not open input file";
return -1;
}
if (avformat_find_stream_info(inputFormatContext, nullptr) < 0) {
qDebug() << "Could not find stream info";
return -1;
}
// 创建输出上下文
QString outputUrl = "rtmp://your-streaming-server-url";
if (avformat_alloc_output_context2(&formatContext, nullptr, "flv", outputUrl.toUtf8().constData()) < 0) {
qDebug() << "Could not allocate output format context";
return -1;
}
outputFormat = formatContext->oformat;
// 找到视频流索引
for (unsigned int i = 0; i < inputFormatContext->nb_streams; ++i) {
if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
stream = avformat_new_stream(formatContext, nullptr);
if (!stream) {
qDebug() << "Failed allocating video stream";
return -1;
}
codecContext = avcodec_alloc_context3(nullptr);
if (!codecContext) {
qDebug() << "Failed to allocate codec context";
return -1;
}
// 复制输入视频流参数到输出流
avcodec_parameters_to_context(codecContext, inputFormatContext->streams[i]->codecpar);
codecContext->codec_tag = 0;
if (formatContext->oformat->flags & AVFMT_GLOBALHEADER)
codecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
break;
}
}
// 设置编码器参数
codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!codec) {
qDebug() << "Could not find H.264 codec";
return -1;
}
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
qDebug() << "Could not open codec";
return -1;
}
av_dump_format(formatContext, 0, outputUrl.toUtf8().constData(), 1);
// 打开输出URL
if (!(outputFormat->flags & AVFMT_NOFILE)) {
if (avio_open2(&formatContext->pb, outputUrl.toUtf8().constData(), AVIO_FLAG_WRITE, nullptr, nullptr) < 0) {
qDebug() << "Could not open output URL";
return -1;
}
}
// 写文件头部
if (avformat_write_header(formatContext, nullptr) < 0) {
qDebug() << "Could not write output file header";
return -1;
}
// 推流循环
while (true) {
AVStream *inputStream = inputFormatContext->streams[0];
if (av_read_frame(inputFormatContext, &packet) < 0)
break;
packet.stream_index = stream->index;
// 调整时间戳
packet.pts = av_rescale_q_rnd(packet.pts, inputStream->time_base, stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
packet.dts = av_rescale_q_rnd(packet.dts, inputStream->time_base, stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
packet.duration = av_rescale_q(packet.duration, inputStream->time_base, stream->time_base);
packet.pos = -1;
if (av_interleaved_write_frame(formatContext, &packet) < 0) {
qDebug() << "Error muxing packet";
av_packet_unref(&packet);
break;
}
av_packet_unref(&packet);
}
// 写文件尾部
av_write_trailer(formatContext);
// 清理资源
avcodec_close(codecContext);
avcodec_free_context(&codecContext);
avio_closep(&formatContext->pb);
avformat_free_context(formatContext);
avformat_close_input(&inputFormatContext);
avformat_network_deinit();
return a.exec();
}
```
在代码中,你需要根据实际情况修改输入视频文件名称和输出的 RTMP 流地址。此示例将输入视频文件推流到指定的 RTMP 流地址。请确保FFmpeg库已正确安装并链接到你的Qt项目中。
这只是一个简单的示例,你可以根据需要进行修改和扩展。
阅读全文