移动网站功能峰峰信息港免费发布平台
news/
2025/9/28 12:22:16/
文章来源:
移动网站功能,峰峰信息港免费发布平台,seo快速优化软件网站,最新的网络营销方式播放器有个功能#xff0c;当用户打开视频时#xff0c;需要读取媒体文件的总时长等信息#xff0c;不巧的时#xff0c;获取FLV时总失败#xff0c;下面来具体分析下FLV和MP4获取总时长的原因和区别#xff1a;
播放器有个获取MediaInfo的接口#xff0c;功能如下当用户打开视频时需要读取媒体文件的总时长等信息不巧的时获取FLV时总失败下面来具体分析下FLV和MP4获取总时长的原因和区别
播放器有个获取MediaInfo的接口功能如下
int MediaFFmpeg::DecoderGetMediaInfo(MediaInfo *mi,AVCodecContext *decodec_ctx,AVStream *stream){if(!mi || !stream || !decodec_ctx){return -1;}//videoif(stream-codecpar-codec_type AVMEDIA_TYPE_VIDEO){//获取视频总时长if(AV_NOPTS_VALUE ! stream-duration){mi-duration stream-duration * av_q2d(stream-time_base);std::cout video_time : (mi-duration / 3600) : (mi-duration % 3600) / 60 : (mi-duration % 60) std::endl;char formatStr[128] {0,};sprintf(formatStr, %02d:%02d:%02d,(mi-duration / 3600),((mi-duration % 3600) / 60),(mi-duration % 60));mi-durationFormatStr formatStr;}else{printf(audio duration unknown ! \n);}mi-width stream-codecpar-width;mi-height stream-codecpar-height;}//audioelse if(stream-codecpar-codec_type AVMEDIA_TYPE_AUDIO){mi-sample_fmt AV_SAMPLE_FMT_S16;mi-sample_rate decodec_ctx-sample_rate; //采样率/*48000; */mi-channels decodec_ctx-channels; //通道数/*1; */mi-nb_samples decodec_ctx-frame_size;/*1024; */mi-audio_buffer_size av_samples_get_buffer_size(NULL, mi-channels, mi-nb_samples, (enum AVSampleFormat)mi-sample_fmt, 1); //输出buff}return 0;
}有经验的人可能很快就能看出来是否存在问题。
总是打印duration不合法
很奇怪的是使用av_dump_format函数可以看到Duration:
Input #0, flv, from /home/zhenghui/视频/1080P.flv:Metadata:major_brand : isomminor_version : 512compatible_brands: isomiso2avc1mp41description : Packed by Bilibili XCoder v2.0.2encoder : Lavf60.3.100Duration: 00:03:46.53, start: 0.000000, bitrate: 3309 kb/sStream #0:0: Video: flv1, yuv420p, 1920x1080, 200 kb/s, 30 fps, 30 tbr, 1k tbnStream #0:1: Audio: adpcm_swf, 44100 Hz, stereo, s16, 352 kb/s就翻了翻ffmpeg的源码找到了av_dump_format的源码
void av_dump_format(AVFormatContext *ic, int index,const char *url, int is_output)
{int i;uint8_t *printed ic-nb_streams ? av_mallocz(ic-nb_streams) : NULL;if (ic-nb_streams !printed)return;av_log(NULL, AV_LOG_INFO, %s #%d, %s, %s %s:\n,is_output ? Output : Input,index,is_output ? ic-oformat-name : ic-iformat-name,is_output ? to : from, url);dump_metadata(NULL, ic-metadata, );if (!is_output) {av_log(NULL, AV_LOG_INFO, Duration: );if (ic-duration ! AV_NOPTS_VALUE) {int64_t hours, mins, secs, us;int64_t duration ic-duration (ic-duration INT64_MAX - 5000 ? 5000 : 0);secs duration / AV_TIME_BASE;us duration % AV_TIME_BASE;mins secs / 60;secs % 60;hours mins / 60;mins % 60;av_log(NULL, AV_LOG_INFO, %02PRId64:%02PRId64:%02PRId64.%02PRId64, hours, mins, secs,(100 * us) / AV_TIME_BASE);} else {av_log(NULL, AV_LOG_INFO, N/A);}if (ic-start_time ! AV_NOPTS_VALUE) {int secs, us;av_log(NULL, AV_LOG_INFO, , start: );secs llabs(ic-start_time / AV_TIME_BASE);us llabs(ic-start_time % AV_TIME_BASE);av_log(NULL, AV_LOG_INFO, %s%d.%06d,ic-start_time 0 ? : -,secs,(int) av_rescale(us, 1000000, AV_TIME_BASE));}av_log(NULL, AV_LOG_INFO, , bitrate: );if (ic-bit_rate)av_log(NULL, AV_LOG_INFO, %PRId64 kb/s, ic-bit_rate / 1000);elseav_log(NULL, AV_LOG_INFO, N/A);av_log(NULL, AV_LOG_INFO, \n);}if (ic-nb_chapters)av_log(NULL, AV_LOG_INFO, Chapters:\n);for (i 0; i ic-nb_chapters; i) {const AVChapter *ch ic-chapters[i];av_log(NULL, AV_LOG_INFO, Chapter #%d:%d: , index, i);av_log(NULL, AV_LOG_INFO,start %f, , ch-start * av_q2d(ch-time_base));av_log(NULL, AV_LOG_INFO,end %f\n, ch-end * av_q2d(ch-time_base));dump_metadata(NULL, ch-metadata, );}if (ic-nb_programs) {int j, k, total 0;for (j 0; j ic-nb_programs; j) {const AVProgram *program ic-programs[j];const AVDictionaryEntry *name av_dict_get(program-metadata,name, NULL, 0);av_log(NULL, AV_LOG_INFO, Program %d %s\n, program-id,name ? name-value : );dump_metadata(NULL, program-metadata, );for (k 0; k program-nb_stream_indexes; k) {dump_stream_format(ic, program-stream_index[k],index, is_output);printed[program-stream_index[k]] 1;}total program-nb_stream_indexes;}if (total ic-nb_streams)av_log(NULL, AV_LOG_INFO, No Program\n);}for (i 0; i ic-nb_streams; i)if (!printed[i])dump_stream_format(ic, i, index, is_output);av_free(printed);
}
av_dump_format函数中使用的是AVFormatContext中的duration而我使用的是AVStream的duration。
Debug了一下AVFormatContext中的duration确实存在
继续跟踪到AVStream的调用位置确实不存在
最终修改如下得已解决
int MediaFFmpeg::DecoderGetMediaInfo(MediaInfo *mi,AVFormatContext *ic,AVCodecContext *decodec_ctx,AVStream *stream){if(!mi || !stream || !decodec_ctx){return -1;}//videoif(stream-codecpar-codec_type AVMEDIA_TYPE_VIDEO){//获取视频总时长if(AV_NOPTS_VALUE ! ic-duration){int64_t hours, mins, secs, us;int64_t duration ic-duration (ic-duration INT64_MAX - 5000 ? 5000 : 0);secs duration / AV_TIME_BASE;us duration % AV_TIME_BASE;mins secs / 60;secs % 60;hours mins / 60;mins % 60;mi-duration duration;char formatStr[128] {0,};sprintf(formatStr, %02ld:%02ld:%02ld,hours,mins,secs);
// mi-duration ic-duration * av_q2d(stream-time_base);
// std::cout video_time :
// (mi-duration / 3600) :
// (mi-duration % 3600) / 60 :
// (mi-duration % 60) std::endl;// char formatStr[128] {0,};
// sprintf(formatStr, %02d:%02d:%02d,
// (mi-duration / 3600),
// ((mi-duration % 3600) / 60),
// (mi-duration % 60));std::cout video_time : formatStr;mi-durationFormatStr formatStr;}else{printf(audio duration unknown ! \n);}mi-width stream-codecpar-width;mi-height stream-codecpar-height;}.........return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920630.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!