12 #include "ffmpegextractor.h"
13 #include "kfilemetadata_debug.h"
15 #include "config-kfilemetadata.h"
18 #define __STDC_CONSTANT_MACROS
26 #include <libavformat/avformat.h>
27 #include <libavutil/dict.h>
28 #include <libavcodec/avcodec.h>
31 using namespace KFileMetaData;
33 FFmpegExtractor::FFmpegExtractor(
QObject* parent)
39 QStringLiteral(
"video/mp4"),
40 QStringLiteral(
"video/mpeg"),
41 QStringLiteral(
"video/quicktime"),
42 QStringLiteral(
"video/webm"),
43 QStringLiteral(
"video/ogg"),
44 QStringLiteral(
"video/mp2t"),
45 QStringLiteral(
"video/x-flv"),
46 QStringLiteral(
"video/x-matroska"),
47 QStringLiteral(
"video/x-ms-wmv"),
48 QStringLiteral(
"video/x-ms-asf"),
49 QStringLiteral(
"video/x-msvideo"),
54 return supportedMimeTypes;
59 AVFormatContext* fmt_ctx =
nullptr;
61 #if LIBAVFORMAT_VERSION_MAJOR < 58
67 fmt_ctx = avformat_alloc_context();
68 if (
int ret = avformat_open_input(&fmt_ctx, arr.
data(),
nullptr,
nullptr)) {
69 qCWarning(KFILEMETADATA_LOG) <<
"avformat_open_input error: " << ret;
73 int ret = avformat_find_stream_info(fmt_ctx,
nullptr);
75 qCWarning(KFILEMETADATA_LOG) <<
"avform_find_stream_info error: " << ret;
81 if (result->
inputFlags() & ExtractionResult::ExtractMetaData) {
82 int totalSecs = fmt_ctx->duration / AV_TIME_BASE;
83 int bitrate = fmt_ctx->bit_rate;
85 result->
add(Property::Duration, totalSecs);
86 result->
add(Property::BitRate, bitrate);
88 const int index_stream = av_find_default_stream_index(fmt_ctx);
89 if (index_stream >= 0) {
90 AVStream* stream = fmt_ctx->streams[index_stream];
92 const AVCodecParameters* codec = stream->codecpar;
94 if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
95 result->
add(Property::Width, codec->width);
96 result->
add(Property::Height, codec->height);
98 AVRational avSampleAspectRatio = av_guess_sample_aspect_ratio(fmt_ctx, stream,
nullptr);
99 AVRational avDisplayAspectRatio;
100 av_reduce(&avDisplayAspectRatio.num, &avDisplayAspectRatio.den,
101 codec->width * avSampleAspectRatio.num,
102 codec->height * avSampleAspectRatio.den,
104 double displayAspectRatio = avDisplayAspectRatio.num;
105 if (avDisplayAspectRatio.den) {
106 displayAspectRatio /= avDisplayAspectRatio.den;
108 if (displayAspectRatio) {
109 result->
add(Property::AspectRatio, displayAspectRatio);
112 AVRational avFrameRate = av_guess_frame_rate(fmt_ctx, stream,
nullptr);
113 double frameRate = avFrameRate.num;
114 if (avFrameRate.den) {
115 frameRate /= avFrameRate.den;
118 result->
add(Property::FrameRate, frameRate);
123 AVDictionary* dict = fmt_ctx->metadata;
124 AVDictionaryEntry* entry;
126 entry = av_dict_get(dict,
"title",
nullptr, 0);
132 entry = av_dict_get(dict,
"author",
nullptr, 0);
137 entry = av_dict_get(dict,
"copyright",
nullptr, 0);
142 entry = av_dict_get(dict,
"comment",
nullptr, 0);
147 entry = av_dict_get(dict,
"album",
nullptr, 0);
152 entry = av_dict_get(dict,
"genre",
nullptr, 0);
157 entry = av_dict_get(dict,
"track",
nullptr, 0);
162 int track = value.
toInt(&ok);
164 result->
add(Property::TrackNumber, track);
168 entry = av_dict_get(dict,
"year",
nullptr, 0);
171 result->
add(Property::ReleaseYear, year);
175 avformat_close_input(&fmt_ctx);