版本:FFMpeg6.0
媒体信息打印
- #include <libavformat/avformat.h>
- #include <libavutil/log.h>
- int main (int argc, char *argv[]) {
- AVFormatContext *fmt_cxt = NULL;
- int ret;
- av_log_set_level(AV_LOG_INFO);
- ret = avformat_open_input(&fmt_cxt, "/root/resource/1.mp4", NULL, NULL);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Can't open file: %s", av_err2str(ret));
- return -1;
- }
- // 打印媒体信息
- av_dump_format(fmt_cxt, 0, "/root/resource/1.mp4", 0);
- avformat_close_input(&fmt_cxt);
-
- return 0;
- }
复制代码 提取音视频
音频和视频的区别在于av_find_best_stream时将AVMEDIA_TYPE_VIDEO改为AVMEDIA_TYPE_AUDIO
- #include <libavformat/avformat.h>
- #include <libavutil/log.h>
- #include <libavutil/avutil.h>
- int main (int argc, char *argv[]) {
- // 1. 处理参数
- char *src;
- char *dst;
- int ret;
- int idx = -1;
- AVFormatContext *pFmtCtx = NULL;
- AVFormatContext *oFmtCtx = NULL;
- const AVOutputFormat *outFmt = NULL;
- AVStream *outStream = NULL;
- AVStream *inStream = NULL;
- AVPacket pkt;
- av_log_set_level(AV_LOG_DEBUG);
- if (argc < 3) {
- av_log(NULL, AV_LOG_ERROR, "argument must be more than 3\n");
- exit(-1);
- }
- src = argv[1];
- dst = argv[2];
- // 2. 打开多媒体文件
- ret = avformat_open_input(&pFmtCtx, src, NULL, NULL);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- exit(-1);
- }
- // 3. 从多媒体文件中找到音频流
- idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
- if (idx < 0) {
- av_log(pFmtCtx, AV_LOG_ERROR, "Does not include audio stream\n");
- goto _ERROR;
- }
- // 4. 打开目的文件的上下文
- oFmtCtx = avformat_alloc_context();
- if (!oFmtCtx) {
- av_log(pFmtCtx, AV_LOG_ERROR, "No memory\n");
- goto _ERROR;
- }
- outFmt = av_guess_format(NULL, dst, NULL);
- oFmtCtx->oformat = outFmt;
- // 5. 为目的文件创建新的音频流
- outStream = avformat_new_stream(oFmtCtx, NULL);
- // 6. 设置输出视频参数
- inStream = pFmtCtx->streams[idx];
- avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
- // 设置为0,会自动去找对应的编码器
- outStream->codecpar->codec_tag = 0;
- ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
-
- // 7. 写多媒体文件头到目的文件
- ret = avformat_write_header(oFmtCtx, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
- // 8. 从源多媒体文件中读音频数据到目的文件中
- while (av_read_frame(pFmtCtx, &pkt) >= 0) {
- if (pkt.stream_index == idx) {
- // 修改时间戳
- pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, (AV_ROUND_INF | AV_ROUND_PASS_MINMAX));
- pkt.dts = av_rescale_q_rnd(pkt.dts, inStream->time_base, outStream->time_base, (AV_ROUND_INF | AV_ROUND_PASS_MINMAX));
- pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);
- pkt.stream_index = 0;
- // 设置成-1,自己会去计算
- pkt.pos = -1;
- av_interleaved_write_frame(oFmtCtx, &pkt);
- av_packet_unref(&pkt);
- }
- }
- // 9. 写多媒体文件尾到目的文件
- av_write_trailer(oFmtCtx);
- // 10. 将申请的资源释放掉
- _ERROR:
- if (pFmtCtx) {
- avformat_close_input(&pFmtCtx);
- pFmtCtx = NULL;
- }
- if (oFmtCtx->pb) {
- avio_close(oFmtCtx->pb);
- }
- if (oFmtCtx) {
- avformat_free_context(oFmtCtx);
- oFmtCtx = NULL;
- }
- return 0;
- }
复制代码 转封装
- #include <libavformat/avformat.h>
- #include <libavutil/log.h>
- #include <libavutil/avutil.h>
- int main (int argc, char *argv[]) {
- // 1. 处理参数
- char *src;
- char *dst;
- int *stream_map = NULL;
- int stream_idx = 0;
- int ret;
- int idx = -1;
- int i = 0;
- AVFormatContext *pFmtCtx = NULL;
- AVFormatContext *oFmtCtx = NULL;
- const AVOutputFormat *outFmt = NULL;
-
- AVPacket pkt;
- av_log_set_level(AV_LOG_DEBUG);
- if (argc < 3) {
- av_log(NULL, AV_LOG_ERROR, "argument must be more than 3\n");
- exit(-1);
- }
- src = argv[1];
- dst = argv[2];
- // 2. 打开多媒体文件
- ret = avformat_open_input(&pFmtCtx, src, NULL, NULL);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- exit(-1);
- }
-
- // 3. 打开目的文件的上下文
- avformat_alloc_output_context2(&oFmtCtx, NULL, NULL, dst);
- if (!oFmtCtx) {
- av_log(NULL, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- stream_map = av_calloc(pFmtCtx->nb_streams, sizeof(int));
- if (!stream_map) {
- av_log(NULL, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- for (i = 0; i < pFmtCtx->nb_streams; ++i) {
- AVStream *outStream = NULL;
- AVStream *inStream = pFmtCtx->streams[i];
- AVCodecParameters *inCodecPar = inStream->codecpar;
- if (inCodecPar->codec_type != AVMEDIA_TYPE_AUDIO &&
- inCodecPar->codec_type != AVMEDIA_TYPE_VIDEO &&
- inCodecPar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
- stream_map[i] = -1;
- continue;
- }
- stream_map[i] = stream_idx++;
- // 4. 为目的文件创建新的音频流
- outStream = avformat_new_stream(oFmtCtx, NULL);
- if (!outStream) {
- av_log(oFmtCtx, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
- // 设置为0,会自动去找对应的编码器
- outStream->codecpar->codec_tag = 0;
- }
-
- ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
-
- // 5. 写多媒体文件头到目的文件
- ret = avformat_write_header(oFmtCtx, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
- // 6. 从源多媒体文件中读音频数据到目的文件中
- while (av_read_frame(pFmtCtx, &pkt) >= 0) {
- AVStream *outStream = NULL;
- AVStream *inStream = NULL;
-
- if (stream_map[pkt.stream_index] < 0) {
- av_packet_unref(&pkt);
- continue;
- }
- inStream = pFmtCtx->streams[pkt.stream_index];
- pkt.stream_index = stream_map[pkt.stream_index];
- outStream = oFmtCtx->streams[pkt.stream_index];
- av_packet_rescale_ts(&pkt, inStream->time_base, outStream->time_base);
- // 设置成-1,自己会去计算
- pkt.pos = -1;
- av_interleaved_write_frame(oFmtCtx, &pkt);
- av_packet_unref(&pkt);
-
- }
- // 7. 写多媒体文件尾到目的文件
- av_write_trailer(oFmtCtx);
- // 8. 将申请的资源释放掉
- _ERROR:
- if (pFmtCtx) {
- avformat_close_input(&pFmtCtx);
- pFmtCtx = NULL;
- }
- if (oFmtCtx->pb) {
- avio_close(oFmtCtx->pb);
- }
- if (oFmtCtx) {
- avformat_free_context(oFmtCtx);
- oFmtCtx = NULL;
- }
- if (stream_map) {
- av_free(stream_map);
- }
- return 0;
- }
复制代码 剪辑
- #include <libavformat/avformat.h>
- #include <libavutil/log.h>
- #include <libavutil/avutil.h>
- #include <stdlib.h>
- int main (int argc, char *argv[]) {
- // 1. 处理参数
- char *src;
- char *dst;
- int *stream_map = NULL;
- int stream_idx = 0;
- int ret;
- int idx = -1;
- int i = 0;
- double startTime = 0;
- double endTime = 0;
- int64_t *dts_start_time = NULL;
- int64_t *pts_start_time = NULL;
- AVFormatContext *pFmtCtx = NULL;
- AVFormatContext *oFmtCtx = NULL;
- const AVOutputFormat *outFmt = NULL;
-
- AVPacket pkt;
- av_log_set_level(AV_LOG_DEBUG);
- // cut src dst start end
- if (argc < 5) {
- av_log(NULL, AV_LOG_ERROR, "argument must be more than 5\n");
- exit(-1);
- }
- src = argv[1];
- dst = argv[2];
- startTime = atof(argv[3]);
- endTime = atof(argv[4]);
- av_log(NULL, AV_LOG_INFO, "hello\n");
- // 2. 打开多媒体文件
- ret = avformat_open_input(&pFmtCtx, src, NULL, NULL);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- exit(-1);
- }
-
- // 4. 打开目的文件的上下文
- avformat_alloc_output_context2(&oFmtCtx, NULL, NULL, dst);
- if (!oFmtCtx) {
- av_log(NULL, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- stream_map = av_calloc(pFmtCtx->nb_streams, sizeof(int));
- if (!stream_map) {
- av_log(NULL, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- for (i = 0; i < pFmtCtx->nb_streams; ++i) {
- AVStream *outStream = NULL;
- AVStream *inStream = pFmtCtx->streams[i];
- AVCodecParameters *inCodecPar = inStream->codecpar;
- if (inCodecPar->codec_type != AVMEDIA_TYPE_AUDIO &&
- inCodecPar->codec_type != AVMEDIA_TYPE_VIDEO &&
- inCodecPar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
- stream_map[i] = -1;
- continue;
- }
- stream_map[i] = stream_idx++;
- // 5. 为目的文件创建新的音频流
- outStream = avformat_new_stream(oFmtCtx, NULL);
- if (!outStream) {
- av_log(oFmtCtx, AV_LOG_ERROR, "NO MEMORY\n");
- goto _ERROR;
- }
- avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
- // 设置为0,会自动去找对应的编码器
- outStream->codecpar->codec_tag = 0;
- }
-
- ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
-
- // 7. 写多媒体文件头到目的文件
- ret = avformat_write_header(oFmtCtx, NULL);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
- // seek
- ret = av_seek_frame(pFmtCtx, -1, startTime * AV_TIME_BASE, AVSEEK_FLAG_BACKWARD);
- if (ret < 0) {
- av_log(oFmtCtx, AV_LOG_ERROR, "%s\n", av_err2str(ret));
- goto _ERROR;
- }
- dts_start_time = av_calloc(pFmtCtx->nb_streams, sizeof(int64_t));
- pts_start_time = av_calloc(pFmtCtx->nb_streams, sizeof(int64_t));
- for (int t = 0; t < pFmtCtx->nb_streams; ++t) {
- dts_start_time[t] = -1;
- pts_start_time[t] = -1;
- }
- // 8. 从源多媒体文件中读音频数据到目的文件中
- while (av_read_frame(pFmtCtx, &pkt) >= 0) {
- AVStream *outStream = NULL;
- AVStream *inStream = NULL;
-
- if (dts_start_time[pkt.stream_index] == -1 && pkt.dts > 0) {
- dts_start_time[pkt.stream_index] = pkt.dts;
- }
- if (pts_start_time[pkt.stream_index] == -1 && pkt.pts > 0) {
- pts_start_time[pkt.stream_index] = pkt.pts;
- }
- if (stream_map[pkt.stream_index] < 0) {
- av_packet_unref(&pkt);
- continue;
- }
- pkt.pts = pkt.pts - pts_start_time[pkt.stream_index];
- pkt.dts = pkt.dts - dts_start_time[pkt.stream_index];
- if (pkt.dts > pkt.pts) {
- pkt.pts = pkt.dts;
- }
- inStream = pFmtCtx->streams[pkt.stream_index];
- if (av_q2d(inStream->time_base) * pkt.pts > endTime) {
- av_log(oFmtCtx, AV_LOG_INFO, "success\n");
- break;
- }
- pkt.stream_index = stream_map[pkt.stream_index];
- outStream = oFmtCtx->streams[pkt.stream_index];
- av_packet_rescale_ts(&pkt, inStream->time_base, outStream->time_base);
- // 设置成-1,自己会去计算
- pkt.pos = -1;
- av_interleaved_write_frame(oFmtCtx, &pkt);
- av_packet_unref(&pkt);
-
- }
- // 9. 写多媒体文件尾到目的文件
- av_write_trailer(oFmtCtx);
- // 10. 将申请的资源释放掉
- _ERROR:
- if (pFmtCtx) {
- avformat_close_input(&pFmtCtx);
- pFmtCtx = NULL;
- }
- if (oFmtCtx->pb) {
- avio_close(oFmtCtx->pb);
- }
- if (oFmtCtx) {
- avformat_free_context(oFmtCtx);
- oFmtCtx = NULL;
- }
- if (stream_map) {
- av_free(stream_map);
- }
- if (pts_start_time) {
- av_free(pts_start_time);
- }
- if (dts_start_time) {
- av_free(dts_start_time);
- }
- return 0;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |