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)