ffmpeg代码保存MP4
时间: 2023-05-24 15:05:39 浏览: 286
要将视频保存为MP4格式,您可以使用以下ffmpeg命令:
```bash
ffmpeg -i input_video_file -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output_video_file.mp4
```
请注意,该命令假定您已经安装了libx264和AAC编解码器。如果没有安装,请先安装这些编解码器。
该命令将输入视频文件(`input_video_file`)编码为H.264视频和AAC音频,并将输出保存为MP4文件(`output_video_file.mp4`),其中:
- `-c:v libx264`:使用libx264编码器将视频编码为H.264格式。
- `-preset medium`:设置编码速度和质量的预设。更快的预设可能会导致较低的视频质量,而更慢的预设可能会提高视频质量但需要更长的时间来编码。在此示例中,我们使用中等预设。
- `-crf 23`:设置视频质量。CRF(constant rate factor)值越低,视频质量越高,文件大小越大。在此示例中,CRF值为23。
- `-c:a aac`:使用AAC编解码器将音频编码为AAC格式。
- `-b:a 128k`:设置音频比特率。在此示例中,比特率为128 kbps。
相关问题
linux C 语言 ffmpeg 摄像头 保存 mp4 视频 完整代码
以下是一个简单的示例代码,使用FFmpeg在Linux上捕获摄像头视频并保存为MP4文件:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#define OUTPUT_FILE "output.mp4"
#define WIDTH 640
#define HEIGHT 480
#define FPS 30
int main() {
int ret;
AVFormatContext *formatContext = NULL;
AVCodecContext *codecContext = NULL;
AVCodec *codec = NULL;
AVStream *stream = NULL;
AVFrame *frame = NULL;
AVPacket packet;
// 初始化FFmpeg
av_register_all();
avformat_network_init();
// 打开摄像头
AVInputFormat *inputFormat = av_find_input_format("video4linux2");
AVDictionary *options = NULL;
av_dict_set(&options, "framerate", "30", 0);
av_dict_set(&options, "video_size", "640x480", 0);
av_dict_set(&options, "input_format", "mjpeg", 0);
if (avformat_open_input(&formatContext, "/dev/video0", inputFormat, &options) < 0) {
fprintf(stderr, "无法打开摄像头\n");
return -1;
}
// 查找解码器
codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
if (!codec) {
fprintf(stderr, "找不到解码器\n");
return -1;
}
// 创建解码器上下文
codecContext = avcodec_alloc_context3(codec);
if (!codecContext) {
fprintf(stderr, "无法创建解码器上下文\n");
return -1;
}
// 打开解码器
if (avcodec_open2(codecContext, codec, NULL) < 0) {
fprintf(stderr, "无法打开解码器\n");
return -1;
}
// 创建输出格式上下文
avformat_alloc_output_context2(&formatContext, NULL, NULL, OUTPUT_FILE);
if (!formatContext) {
fprintf(stderr, "无法创建输出格式上下文\n");
return -1;
}
// 创建视频流
stream = avformat_new_stream(formatContext, NULL);
if (!stream) {
fprintf(stderr, "无法创建视频流\n");
return -1;
}
// 设置视频流参数
codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
codecContext->width = WIDTH;
codecContext->height = HEIGHT;
codecContext->time_base = (AVRational){1, FPS};
codecContext->framerate = (AVRational){FPS, 1};
// 复制解码器上下文到视频流
if (avcodec_parameters_from_context(stream->codecpar, codecContext) < 0) {
fprintf(stderr, "无法复制解码器上下文到视频流\n");
return -1;
}
// 打开输出文件
if (avio_open(&formatContext->pb, OUTPUT_FILE, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "无法打开输出文件\n");
return -1;
}
// 写入文件头
if (avformat_write_header(formatContext, NULL) < 0) {
fprintf(stderr, "无法写入文件头\n");
return -1;
}
// 创建帧
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "无法创建帧\n");
return -1;
}
frame->format = codecContext->pix_fmt;
frame->width = codecContext->width;
frame->height = codecContext->height;
// 分配帧数据空间
ret = av_image_alloc(frame->data, frame->linesize, codecContext->width, codecContext->height, codecContext->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "无法分配帧数据空间\n");
return -1;
}
// 初始化像素格式转换上下文
struct SwsContext *swsContext = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt,
codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P,
0, NULL, NULL, NULL);
// 读取摄像头数据并写入文件
while (1) {
// 读取摄像头数据
if (av_read_frame(formatContext, &packet) < 0)
break;
// 解码帧
if (avcodec_send_packet(codecContext, &packet) < 0) {
fprintf(stderr, "解码错误\n");
break;
}
while (avcodec_receive_frame(codecContext, frame) == 0) {
// 转换像素格式
sws_scale(swsContext, frame->data, frame->linesize, 0, codecContext->height, frame->data, frame->linesize);
// 写入文件
av_write_frame(formatContext, &packet);
}
av_packet_unref(&packet);
}
// 写入文件尾
av_write_trailer(formatContext);
// 清理资源
av_frame_free(&frame);
avcodec_free_context(&codecContext);
avformat_close_input(&formatContext);
avio_close(formatContext->pb);
avformat_free_context(formatContext);
return 0;
}
```
请注意,这只是一个基本的示例代码,可能还需要进行一些错误处理和其他的功能扩展。在编译代码之前,请确保已经安装了FFmpeg开发库,并使用适当的编译选项链接所需的库。
编译命令示例:
```shell
gcc -o capture_video capture_video.c -lavformat -lavcodec -lavutil -lswscale
```
运行生成的可执行文件即可开始捕获摄像头视频并将其保存为MP4文件。
ffmpeg读取MP4文件保存jpg
ffmpeg读取MP4文件并保存为jpg的主要函数部分如下所示:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
int main(int argc, char *argv[]) {
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = NULL;
AVPacket packet;
int videoStream = -1;
int frameFinished = 0;
int numBytes;
uint8_t *buffer = NULL;
struct SwsContext *sws_ctx = NULL;
int i;
// 打开输入文件
if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) {
fprintf(stderr, "Could not open input file '%s'\n", argv[1]);
return -1;
}
// 获取流信息
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
fprintf(stderr, "Could not find stream information\n");
return -1;
}
// 查找视频流
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
break;
}
}
if (videoStream == -1) {
fprintf(stderr, "Could not find video stream\n");
return -1;
}
// 获取视频解码器
pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);
if (pCodec == NULL) {
fprintf(stderr, "Unsupported codec\n");
return -1;
}
// 初始化解码器上下文
pCodecCtx = avcodec_alloc_context3(pCodec);
if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar) < 0) {
fprintf(stderr, "Failed to copy codec parameters to decoder context\n");
return -1;
}
// 打开解码器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
fprintf(stderr, "Failed to open codec\n");
return -1;
}
// 分配帧内存
pFrame = av_frame_alloc();
if (pFrame == NULL) {
fprintf(stderr, "Failed to allocate frame\n");
return -1;
}
// 分配缓冲区
numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 1);
buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
// 初始化SwsContext
sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24,
SWS_BILINEAR, NULL, NULL, NULL);
// 读取帧并保存为jpg
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoStream) {
avcodec_send_packet(pCodecCtx, &packet);
avcodec_receive_frame(pCodecCtx, pFrame);
// 转换像素格式
sws_scale(sws_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrame->data, pFrame->linesize);
// 保存为jpg文件
char filename[256];
sprintf(filename, "frame%d.jpg", i++);
FILE *file = fopen(filename, "wb");
fwrite(buffer, 1, numBytes, file);
fclose(file);
}
av_packet_unref(&packet);
}
// 释放资源
av_free(buffer);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
```
请注意,上述代码只是一个示例,可能需要根据实际情况进行适当的修改和调整。此外,还需要包含相应的头文件和链接相应的库文件。
阅读全文