12#include "ffmpegextractor.h"
13#include "kfilemetadata_debug.h"
15#include "config-kfilemetadata.h"
18#define __STDC_CONSTANT_MACROS
26#include <libavcodec/avcodec.h>
27#include <libavformat/avformat.h>
28#include <libavutil/avutil.h>
29#include <libavutil/dict.h>
30#include <libavutil/pixdesc.h>
35FFmpegExtractor::FFmpegExtractor(
QObject* parent)
41 QStringLiteral(
"video/mp2t"),
42 QStringLiteral(
"video/mp4"),
43 QStringLiteral(
"video/mpeg"),
44 QStringLiteral(
"video/ogg"),
45 QStringLiteral(
"video/quicktime"),
46 QStringLiteral(
"video/vnd.avi"),
47 QStringLiteral(
"video/webm"),
48 QStringLiteral(
"video/x-flv"),
49 QStringLiteral(
"video/x-matroska"),
50 QStringLiteral(
"video/x-ms-asf"),
51 QStringLiteral(
"video/x-ms-wmv"),
52 QStringLiteral(
"video/x-msvideo"),
57 return supportedMimeTypes;
62 AVFormatContext* fmt_ctx =
nullptr;
64#if LIBAVFORMAT_VERSION_MAJOR < 58
70 fmt_ctx = avformat_alloc_context();
71 if (
int ret = avformat_open_input(&fmt_ctx, arr.
data(),
nullptr,
nullptr)) {
72 qCWarning(KFILEMETADATA_LOG) <<
"avformat_open_input error: " << ret;
76 int ret = avformat_find_stream_info(fmt_ctx,
nullptr);
78 qCWarning(KFILEMETADATA_LOG) <<
"avform_find_stream_info error: " << ret;
84 if (result->
inputFlags() & ExtractionResult::ExtractMetaData) {
85 int totalSecs = fmt_ctx->duration / AV_TIME_BASE;
86 int bitrate = fmt_ctx->bit_rate;
91 const int index_stream = av_find_default_stream_index(fmt_ctx);
92 if (index_stream >= 0) {
93 AVStream* stream = fmt_ctx->streams[index_stream];
95 const AVCodecParameters* codec = stream->codecpar;
97 if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
101 AVRational avSampleAspectRatio = av_guess_sample_aspect_ratio(fmt_ctx, stream,
nullptr);
102 AVRational avDisplayAspectRatio;
103 av_reduce(&avDisplayAspectRatio.num, &avDisplayAspectRatio.den,
104 codec->width * avSampleAspectRatio.num,
105 codec->height * avSampleAspectRatio.den,
107 double displayAspectRatio = avDisplayAspectRatio.num;
108 if (avDisplayAspectRatio.den) {
109 displayAspectRatio /= avDisplayAspectRatio.den;
111 if (displayAspectRatio) {
115 AVRational avFrameRate = av_guess_frame_rate(fmt_ctx, stream,
nullptr);
116 double frameRate = avFrameRate.num;
117 if (avFrameRate.den) {
118 frameRate /= avFrameRate.den;
126 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((AVPixelFormat)codec->format);
135 const auto audio_index_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1,
nullptr, 0);
136 if (audio_index_stream >= 0) {
137 AVStream* stream = fmt_ctx->streams[audio_index_stream];
139 const AVCodecParameters* codec = stream->codecpar;
143 AVDictionary* dict = fmt_ctx->metadata;
146 if (!dict && fmt_ctx->nb_streams > 0) {
147 dict = fmt_ctx->streams[0]->metadata;
150 AVDictionaryEntry* entry;
152 entry = av_dict_get(dict,
"title",
nullptr, 0);
158 entry = av_dict_get(dict,
"author",
nullptr, 0);
163 entry = av_dict_get(dict,
"copyright",
nullptr, 0);
168 entry = av_dict_get(dict,
"comment",
nullptr, 0);
173 entry = av_dict_get(dict,
"album",
nullptr, 0);
178 entry = av_dict_get(dict,
"genre",
nullptr, 0);
183 entry = av_dict_get(dict,
"track",
nullptr, 0);
188 int track = value.
toInt(&ok);
194 entry = av_dict_get(dict,
"year",
nullptr, 0);
201 avformat_close_input(&fmt_ctx);
204#include "moc_ffmpegextractor.cpp"
QString fromUtf8(QByteArrayView str)
int toInt(bool *ok, int base) const const
QByteArray toUtf8() const const