feat: add Matroska/WebM (mkv/webm) file support with library duration - #16886
feat: add Matroska/WebM (mkv/webm) file support with library duration#16886hdp1972be-svg wants to merge 8 commits into
Conversation
Add the "mkv" and "webm" suffixes to the file types reported by the FFmpeg sound source provider, so Matroska/WebM files become selectable.
Remove the leftover "}" from the previous commit so the mkv/webm branch ends after "continue;" as intended.
Qt's QMimeDatabase may not recognize Matroska/WebM containers from content, so resolve the type by file suffix for mkv/webm instead. add mkv and webm in soundsource
Matroska/WebM streams often report an unknown stream duration. Use the format context duration as a fallback so such files can be opened and seeked correctly.
The duration fallback for streams with unknown duration assigned AVFormatContext::duration, which is measured in AV_TIME_BASE units (1/1e6 s), directly to AVStream::duration, which is measured in stream time_base units. For webm/mkv streams with a 1/1000 s time base this inflated the frame index range by ~1000x, breaking seeking and the waveform/spectrogram (e.g. "Stream ends at sample frame 18534900 instead of 18535728336"). Rescale the duration with av_rescale_q before assigning it.
TagLib does not support Matroska/WebM containers, so MetadataSourceTagLib returns ImportResult::Unavailable for these file types. As a result the library showed an empty duration column for such files, because the FFmpeg-based SoundSource never fed the imported stream info back into the track metadata. Add an importTrackMetadataAndCoverImage override that delegates all TagLib-supported file types to the default implementation, and for mkv/webm opens the FFmpeg container and reports the stream info (channel count, sample rate, bitrate and duration) matching the native values used by initResampling(). The duration is derived from the stream frame index range, mirroring the format-context duration fallback of tryOpen() when the stream duration is unknown.
2392dd5 to
f2150d7
Compare
|
Which taglib version did you tried? taglib official supports Matroska. |
|
My system has a custom build o taglib v2.0.2 in /usr/local which gave always an Unknown filetype respons. That's the reason I branched it to a more native ffmpeg duration implementation. In the focal-CI for building I use 1.11.1 (alas, same problem) However, it seems - indeed - that mkv support was added in taglib but only version 2.2 (Feb 2026) upwards. (confirmed in taglib CHANGELOG) In mixxx requirements taglib (the find_package(TagLib 1.11 REQUIRED) ) a minimum of taglib 1.11 is required. If needed or wanted I could implement a check on the version of taglib in the code too and if >=2.2 is found use taglib support for mkv/webm ; i.e. add/use the path in trackmetadata_file.cpp. Otherwise fallback on the ffmpeg support. That patch (not upstream pushed atm) is actually 90% ready, I only need to check it if it compiles and works correctly in my CI and make another workflow file to test it against the v2.2 version of taglib. |
|
We've another PR #15888 by @acolombier where taglib 2.2 is needed. As soon as Ubuntu 26.04.01 is out, we will raise the minimum requirement according to our policy. |
|
As a first-time contributor we need you to sign the Mixxx Contributor Agreement and comment here when you have done so. It gives us permission to distribute your contribution under the GPL v2 or later license and the Apple Mac App Store. It is also helpful for us to have contact information for contributors in case we may need it in the future. |
|
Upgrading to taglib 2.2 alone doesn't solve the issue completely, because
However it's good to know the dependency to taglib will be bumped to v2.2 when 26.04.01 will come out. I will add a bit of code around the patch so depending on the taglib version it branches to the specific code. So in the end it will do
Working on the implementation of cover art too, so the first non-black frame of the 1st video stream (if there is one) is taken as cover art pic) (in progress) I've build this PR (without the taglib 2.2 implementation code) against taglib and it doesn't break anything. Different taglib dependency versions (2.2 and 1.x) can be checked (if needed) here Contributor agreement -> signed |
|
Please note, that Mixxx is a cross-platform software and for legal issues we can use FFmpeg only very limited. But taglib we can use on any platform. |
|
Okay, ffmpeg info noted. Can uou elabotate more which exact FFmpeg use is restricted so I can make sure the implementation stays within those constraints? As far as I'm aware, this PR does not introduce any new FFmpeg functionality or a new SoundSource; it only extends the existing FFmpeg SoundSource path to handle Matroska/WebM with FFmpeg being used as a fallback where TagLib <2.2 doesn't provide the required information. The TagLib 2.2 implementation, including the conditional compilation, will be done as well, but that's beyond the scope of this PR. I also saw the failed test: SoundSourceProxyTest.taglibStringToEnumFileType. Could you provide the exact failure output for that test? (which is unviewabe from the CI pre-commit workflow)/ I suspect it may be related to the difference between the file types supported by FFmpeg and those supported by TagLib, but I'd like to confirm the exact failing type. |
feat: add Matroska/WebM (mkv/webm) file support with library duration
Text is partly AI written as I am no native english language speaker, however manually checked against errors.
Code patches are checked on a ubuntu 20.04 container, build with CI, then tested on a 20.04 system.
All features tested manually, code reviewed by hand.
tested with ffmpeg 4.2.7, custom compiled QT6 (so it works on 20.04)
Motivation
The FFmpeg sound source provider already advertises
.mkvand.webm, andsuch files can be opened and played. However, the library showed an empty
Duration column for these files.
Root cause:
SoundSourceFFmpeghad no metadata override, so no stream info was importedfrom the container.
MetadataSourceTagLibreturnedImportResult::Unavailablefor mkv/webm(TagLib cannot read these containers), which made
updateTrackFromSource()skip the import entirely.
Changes
feat: advertise MKV/WebM as supported file types— register themkv/webmsuffixes inSoundSourceProviderFFmpeg::getSupportedFileTypes().fix: drop stray brace from MKV/WebM file type block— cleanup of theprevious commit.
fix: bypass content mime lookup for MKV/WebM— resolve the sound sourcetype by file suffix in
SoundSource::getTypeFromFile(), because Qt'sQMimeDatabasemay not recognize Matroska/WebM from content.Add mkv/webm bypass in MetadataSourceTagLib— returnImportResult::Unavailablefor mkv/webm so the FFmpeg path is used,avoiding a TagLib "unsupported type" warning.
Add QFileInfo include for TagLib mkv/webm bypass— needed include for thesuffix check.
fix: fall back to format context duration for MKV/WebM— intryOpen(),use the format context duration when the stream duration is
AV_NOPTS_VALUEinstead of failing to open.fix: rescale format context duration to stream time base— rescale thecontainer duration to the stream time base before use.
feat: import Matroska/WebM stream info from FFmpeg container— newimportTrackMetadataAndCoverImage()override inSoundSourceFFmpegthatopens the container, picks the audio stream with
av_find_best_stream, andimports duration, channels, sample rate and bitrate from
AVCodecParameters.All other file types are delegated to
MetadataSourceTagLib.