ffmpeg视频格式转换
方法1:命令转换
ffmpeg -i input.mp4 output.flv
方法2:代码转换

main.c
#include "libavutil/log.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavcodec/avcodec.h"
int main(int argc, char **argv) {
av_log_set_level(AV_LOG_DEBUG);
if (argc < 3) {
av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile outputFile\n", argv[0]);
return -1;
}
const char *inputFile = argv[1];
const char *outputFile = argv[2];
AVFormatContext *fCtx = NULL;
int ret;
ret = avformat_open_input(&fCtx, inputFile, NULL, NULL);
if (ret != 0) {
av_log(NULL, AV_LOG_ERROR, "Open input file %s failed: %s\n", inputFile, av_err2str(ret));
return -1;
}
ret = avformat_find_stream_info(fCtx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Find input file stream info failed: %s\n", av_err2str(ret));
avformat_close_input(&fCtx);
return -1;
}
AVFormatContext *outCtx = NULL;
ret = avformat_alloc_output_context2(&outCtx, NULL, NULL, outputFile);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "avformat_alloc_output_context2 failed: %s\n", av_err2str(ret));
avformat_close_input(&fCtx);
avformat_free_context(outCtx);
return -1;
}
unsigned int streamCount = fCtx->nb_streams;
int *handleStreamIndexArray = av_mallocz_array(streamCount, sizeof(unsigned int));
if (handleStreamIndexArray == NULL) {
av_log(NULL, AV_LOG_ERROR, "av_mallocz_array failed: %s\n", av_err2str(ret));
ret = -1;
goto clean;
}
int streamIndex = 0;
for (int i = 0; i < streamCount; i++) {
AVStream *inStream = fCtx->streams[i];
if (inStream->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
inStream->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
inStream->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
handleStreamIndexArray[i] = -1;
continue;
} else {
handleStreamIndexArray[i] = streamIndex++;
AVStream *outStream = NULL;
outStream = avformat_new_stream(outCtx, NULL);
if (outStream == NULL) {
av_log(NULL, AV_LOG_ERROR, "avformat_new_stream failed");
ret = -1;
goto clean;
}
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
}
}
if (!(outCtx->oformat->flags & AVFMT_NOFILE)) {
ret = avio_open(&outCtx->pb, outputFile, AVIO_FLAG_WRITE);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "avio_open failed: %s\n", av_err2str(ret));
ret = -1;
goto clean;
}
}
ret = avformat_write_header(outCtx, NULL);
if (ret != AVSTREAM_INIT_IN_WRITE_HEADER) {
av_log(NULL, AV_LOG_ERROR, "avformat_write_header failed: %s\n", av_err2str(ret));
ret = -1;
goto clean;
}
AVPacket *packet = av_packet_alloc();
while (av_read_frame(fCtx, packet) == 0) {
if (packet->stream_index >= streamCount || handleStreamIndexArray[packet->stream_index] == -1) {
av_packet_unref(packet);
continue;
}
AVStream *inStream = fCtx->streams[packet->stream_index];
AVStream *outStream = outCtx->streams[packet->stream_index];
packet->stream_index = handleStreamIndexArray[packet->stream_index];
packet->pts = av_rescale_q(packet->pts, inStream->time_base, outStream->time_base);
packet->dts = av_rescale_q(packet->dts, inStream->time_base, outStream->time_base);
packet->duration = av_rescale_q(packet->duration, inStream->time_base, outStream->time_base);
packet->pos = -1;
ret = av_interleaved_write_frame(outCtx, packet);
if (ret != 0) {
av_log(NULL, AV_LOG_ERROR, "av_interleaved_write_frame failed: %s\n", av_err2str(ret));
ret = -1;
goto clean;
}
av_packet_unref(packet);
}
ret = av_write_trailer(outCtx);
if (ret != 0) {
av_log(NULL, AV_LOG_ERROR, "av_write_trailer failed: %s\n", av_err2str(ret));
ret = -1;
goto clean;
}
ret = 0;
clean:
if (fCtx != NULL) {
avformat_close_input(&fCtx);
}
if (outCtx != NULL) {
avformat_free_context(outCtx);
}
return ret;
}
Makefile
TARGET=main
SRC=main.c
CC=gcc
CFLAGS=-I /usr/local/ffmpeg/include
LDFLAGS=-L /usr/local/ffmpeg/lib
LDFLAGS+= -lavutil -lavformat -lavcodec
all:$(TARGET)
$(TARGET):$(SRC)
$(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(TARGET)
clean:
rm -rf $(TARGET)

浙公网安备 33010602011771号