Skip to content

Matroska (mkv) support#688

Open
Tophness wants to merge 5 commits intoquodlibet:mainfrom
Tophness:main
Open

Matroska (mkv) support#688
Tophness wants to merge 5 commits intoquodlibet:mainfrom
Tophness:main

Conversation

@Tophness
Copy link

Successfully tested read and write functionality, all up to spec with the RFC standard.
#3 #575

@Tophness
Copy link
Author

Tophness commented Sep 30, 2025

Read test:

import sys
from mutagen.mkv import MKVFile


def test_mkv_file(file_path):
    if not os.path.exists(file_path):
        print(f"Error: File not found: {file_path}")
        return

    file_size = os.path.getsize(file_path)
    print(f"\nTesting file: {file_path} ({file_size} bytes)")
    print("=" * 80)

    try:
        mkv = MKVFile(file_path)
        print("\nReading metadata:")
        print_metadata(mkv)
    except Exception as e:
        print(f"Error reading {file_path}: {e}")
        import traceback
        traceback.print_exc()


def _print_value(value, indent_level):
    indent = " " * indent_level
    if isinstance(value, bytes):
        try:
            value_str = value.decode('utf-8', errors='replace')
            print(f"{indent}{value_str}")
        except Exception:
            print(f"{indent}0x{value.hex()}")
    else:
        print(f"{indent}{value}")


def print_metadata(mkv):
    if not mkv.tags:
        print("No metadata found in the file.")
        return

    print("Metadata found:")
    for key, value in sorted(mkv.tags.items()):
        if isinstance(value, list):
            print(f"  {key}:")
            for item in value:
                _print_value(item, indent_level=4)
        else:
            print(f"  {key}: ", end="")
            _print_value(value, indent_level=0)


if __name__ == "__main__":
    if len(sys.argv) > 1:
        for file_path in sys.argv[1:]:
            test_mkv_file(file_path)
    else:
        print("Please provide MKV file paths as arguments.")
        print("Usage: python test_mkv.py [file1.mkv file2.mkv ...]")```

@Tophness
Copy link
Author

Tophness commented Sep 30, 2025

Write test:

import shutil
from mutagen.mkv import MKVFile

def test_mkv_write():
    input_file = r"input.mkv"
    output_file = r"output.mkv"

    if not os.path.exists(input_file):
        print(f"Error: Input file not found at '{input_file}'")
        print("Please ensure the file exists or modify the 'input_file' variable.")
        return

    # --- Test Execution ---
    print(f"Using input file: {input_file}")
    print(f"Will create and modify: {output_file}\n")

    # 1. Copy the file to avoid modifying the original
    try:
        shutil.copyfile(input_file, output_file)
        print(f"Successfully copied '{input_file}' to '{output_file}'.")
    except Exception as e:
        print(f"Error copying file: {e}")
        return

    # 2. Read the original comment tag
    try:
        mkv = MKVFile(output_file)
        original_comment = mkv.tags.get('COMMENT')
        if original_comment:
            print(f"Original 'COMMENT' tag: '{original_comment[0]}'")
        else:
            print("No 'COMMENT' tag found in the original file.")
    except Exception as e:
        print(f"Error reading tags from '{output_file}': {e}")
        return

    # 3. Set a new comment tag and save the file
    new_comment_value = "test"
    print(f"\nSetting 'COMMENT' tag to: '{new_comment_value}'")
    try:
        mkv.tags['COMMENT'] = new_comment_value
        mkv.save()
        print("Successfully saved the file with the new tag.")
    except Exception as e:
        print(f"Error saving file '{output_file}': {e}")
        return

    # 4. Read the file again to verify the change
    print("\nVerifying the change...")
    try:
        mkv_verify = MKVFile(output_file)
        written_comment = mkv_verify.tags.get('COMMENT')
        
        if written_comment:
            print(f"Read back 'COMMENT' tag: '{written_comment[0]}'")
            if written_comment[0] == new_comment_value:
                print("\n--- VERIFICATION SUCCESSFUL ---")
                print("The 'COMMENT' tag was written and read back correctly.")
            else:
                print("\n--- VERIFICATION FAILED ---")
                print(f"Expected '{new_comment_value}' but got '{written_comment[0]}'")
        else:
            print("\n--- VERIFICATION FAILED ---")
            print("The 'COMMENT' tag was not found after saving.")
            
    except Exception as e:
        print(f"Error during verification read of '{output_file}': {e}")

if __name__ == "__main__":
    test_mkv_write()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant