Giter Site home page Giter Site logo

sheldonkwoodward / pymkv Goto Github PK

View Code? Open in Web Editor NEW
74.0 3.0 26.0 130 KB

A Python wrapper for mkvmerge. It provides support for muxing, splitting, linking, chapters, tags, and attachments through the use of mkvmerge.

License: MIT License

Python 100.00%
mkvmerge mkvtoolnix muxer

pymkv's Introduction

pymkv

PyPI Version License Code Quality

pymkv is a Python wrapper for mkvmerge and other tools in the MKVToolNix suite. It provides support for muxing, splitting, linking, chapters, tags, and attachments through the use of mkvmerge.

About pymkv

pymkv is a Python 3 library for manipulating MKV files with mkvmerge. Constructing mkvmerge commands manually can quickly become confusing and complex. To remedy this, I decided to write this library to make mkvmerge more scriptable and easier to use. Please open new issues for any bugs you find, support is greatly appreciated!

Installation

mkvmerge must be installed on your computer, it is needed to process files when creating MKV objects. It is also recommended to add it to your $PATH variable but a different path can be manually specified. mkvmerge can be found and downloaded from here or from most package managers.

To install pymkv from PyPI, use the following command:

$ pip install pymkv

You can also clone the repo and run the following command in the project root to install the source code as editable:

$ pip install -e .

Documentation

The documentation for pymkv can be found here or in the project's docstrings.

Roadmap

pymkv was a project started a few years ago when I was first learning Python. There were a number of things that I did that could use improvement. The planned changes and future features are outlined below. Keep an eye on the Github Projects page for the current roadmap status.

Documentation

The current documentation for pymkv is lacking. Instead of manually managing a GitHub Wiki, Sphinx will be setup to automatically generate documentation from docstrings. The docstrings will also need to be updated and improved to ensure this documentation is complete.

Tests

After completing documentation for the existing features, unit tests need to be written to "lock in" the existing functionality. Generating mkvmerge commands can be complex and it is easy to subtly modify an existing feature when adding a new one. Unit tests will ensure that features remain the same and help prevent bugs in the future.

Cleanup

The existing code base could use some tidying, better commenting, debugging, and a general styling overhaul. Setting up pre-commit and the Black code formatter will help keep the code base more readable and maintainable.

Features

Once these first three steps are complete, pymkv will be ready to start adding new features. The goal is for pymkv to implement the functionality of mkvmerge and other MKVToolNix tools as closely as possible. New features and bugs will be added to the GitHub issues page. As pymkv progresses through the previous steps, this roadmap will be expanded to outline new features.

pymkv's People

Contributors

goldbergdata avatar joshuaavalon avatar sheldonkwoodward avatar smahot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pymkv's Issues

Allow setting character set for subtitles

When adding subtitles, while there is an option to set the language, there is no option to set the character set.
This leads to incorrect display for international files.
--sub-charset is the associated flag.

UTF-8 - malformed
ISO-8859-15 - correct

Example (SRT):
sample.de.srt.txt

Attachments are not showing up properly

I've got an mkv file with a number of attachments that show up when running mkvmerge manually, but they aren't showing up when using MKVFile.attachments:

sub-extractor on ๎‚  master [?] is ๐Ÿ“ฆ v0.1.0 via ๐Ÿ v3.8.6 
โฏ poetry run sub-extractor --dir . --clear
{'_track_codec': 'MPEG-4p10/AVC/H.264', '_track_type': 'video', 'mkvmerge_path': 'mkvmerge', '_file_path': 'test.mkv', '_track_id': 0, 'track_name': None, '_language': 'eng', '_tags': None, 'default_track': True, 'forced_track': False, 'no_chapters': False, 'no_global_tags': False, 'no_track_tags': False, 'no_attachments': False}
{'_track_codec': 'AAC', '_track_type': 'audio', 'mkvmerge_path': 'mkvmerge', '_file_path': 'test.mkv', '_track_id': 1, 'track_name': None, '_language': 'jpn', '_tags': None, 'default_track': True, 'forced_track': False, 'no_chapters': False, 'no_global_tags': False, 'no_track_tags': False, 'no_attachments': False}
{'_track_codec': 'SubStationAlpha', '_track_type': 'subtitles', 'mkvmerge_path': 'mkvmerge', '_file_path': 'test.mkv', '_track_id': 2, 'track_name': None, '_language': 'eng', '_tags': None, 'default_track': True, 'forced_track': False, 'no_chapters': False, 'no_global_tags': False, 'no_track_tags': False, 'no_attachments': False}

0

sub-extractor on ๎‚  master [?] is ๐Ÿ“ฆ v0.1.0 via ๐Ÿ v3.8.6 
โฏ mkvmerge -i test.mkv                                                      
File 'test.mkv': container: Matroska
Track ID 0: video (MPEG-4p10/AVC/H.264)
Track ID 1: audio (AAC)
Track ID 2: subtitles (SubStationAlpha)
Attachment ID 1: type 'application/x-truetype-font', size 170160 bytes, file name 'KGHAPPY.ttf'
Attachment ID 2: type 'application/x-truetype-font', size 62536 bytes, file name 'LT_C.ttf'
Attachment ID 3: type 'application/x-truetype-font', size 62480 bytes, file name 'LTFinnegan_MediumItalic_0.ttf'
Attachment ID 4: type 'application/x-truetype-font', size 116172 bytes, file name 'Mermaid1001.ttf'
Attachment ID 5: type 'application/x-truetype-font', size 50348 bytes, file name 'Polo Brush.ttf'
Attachment ID 6: type 'application/x-truetype-font', size 20728 bytes, file name 'Scratch.ttf'
Attachment ID 7: type 'application/x-truetype-font', size 36452 bytes, file name 'SetFireToTheRain.ttf'
Attachment ID 8: type 'application/x-truetype-font', size 53968 bytes, file name 'Arial Rounded MT.ttf'
Attachment ID 9: type 'application/x-truetype-font', size 57808 bytes, file name 'Folder_Bold.ttf'
Attachment ID 10: type 'application/vnd.ms-opentype', size 17028 bytes, file name 'FOTCometStdStripped-Bold_0.otf'
Attachment ID 11: type 'application/x-truetype-font', size 152700 bytes, file name 'FRABK.TTF'
Attachment ID 12: type 'application/x-truetype-font', size 142932 bytes, file name 'FRADM.TTF'
Attachment ID 13: type 'application/x-truetype-font', size 139332 bytes, file name 'framd_0.ttf'
Attachment ID 14: type 'application/x-truetype-font', size 42108 bytes, file name 'GOTH720K.TTF'
Attachment ID 15: type 'application/x-truetype-font', size 67056 bytes, file name 'Janetta Silloam.otf'
Chapters: 6 entries

Here's the function that was being called:

def extract_subs_and_fonts(
    mkv_file: Path,
    mkv_dir: Path,
):
    mkv_obj = MKVFile(mkv_file)
    for track in mkv_obj.tracks:
        print(track)
    print()
    print(len(mkv_obj.attachments))

Missing codec and type information in MKVTrack when initializing MKVFile

I'm thinking about using this library. Seems to me that when a MKVFile instance is created based on existing file, no codec (e.g. MPEG-4p10/AVC/h.264) or type (e.g. video) is saved to the created MKVTrack instances. I think that info should be added, it's available in the output of mkvmerge.

move_track_front() and move_track_end() don't work

For MKVFiles, the functions move_track_front() and move_track_end don't work properly. Line 259 in move_track_front() should be changed from

self.tracks.insert(0, self.tracks.pop(self.tracks[track_num]))

to something like

self.tracks.insert(0, self.tracks.pop(track_num))

A similar fix will apply to line 270 in move_track_end().

Removing multiple track at once doesn't produce the expected result

Hello,

I have an MKV with a total of 8 tracks, I'm trying to remove 2 of them:

mkv = MKVFile('/path/to/file.mkv')
mkv.remove_track(5)
mkv.remove_track(7)
mkv.mux('/path/to/output.mkv')

The produced file has the track 5 successfully removed (it seems?) but the track 7 is still there and the track 8 has been removed but I wanted to keep it ...

Removing a single track seems to work however.

Is the removal of multiple tracks at once supposed to be working ?

French language code

Hi,

Thanks a lot for the library.
In mkv files, french language code is 'fre' and not 'fra'.
It currently leads to an error 'ValueError: not an ISO639-2 language code'.

Custom exceptions

The current exception methodology uses the built in Python exceptions. Custom exceptions should be written to replace most of the built in usages to be more specific.

Adding any kind of video, removes the audio track

Describe the bug
When adding a non MKV video it ignores the audio track and final mkv does not have audio.
tried #44 using file_path but since video is not MKV, it does not work

To Reproduce

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pymkv
mkv = pymkv.MKVFile()

"""
mkvmerge -J video_with_audio.mp4

{
    "attachments": [],
    "chapters": [],
    "container": {
        "properties": {
            "container_type": 25,
            "is_providing_timestamps": true
        },
        "recognized": true,
        "supported": true,
        "type": "QuickTime/MP4"
    },
    "errors": [],
    "file_name": "video_with_audio.mp4",
    "global_tags": [],
    "identification_format_version": 12,
    "track_tags": [],
    "tracks": [
        {
            "codec": "MPEG-4p10/AVC/H.264",
            "id": 0,
            "properties": {
                "language": "und",
                "number": 1,
                "packetizer": "mpeg4_p10_video",
                "pixel_dimensions": "1920x800"
            },
            "type": "video"
        },
        {
            "codec": "AAC",
            "id": 1,
            "properties": {
                "audio_bits_per_sample": 16,
                "audio_channels": 6,
                "audio_sampling_frequency": 48000,
                "language": "und",
                "number": 2
            },
            "type": "audio"
        }
    ],
    "warnings": []
}
"""

mkv.add_track('video_with_audio.mp4')
mkv.add_track(pymkv.MKVTrack('eng.srt', track_name='English', language='eng'))
mkv.add_track(pymkv.MKVTrack('spa.srt', track_name='Spanish', language='spa'))

mkv.mux('final_video.mkv')

Expected behavior
Add audio and video tracks

Screenshots

mkvmerge -J final_video.mkv
{
    "attachments": [],
    "chapters": [],
    "container": {
        "properties": {
            "container_type": 17,
            "date_local": "2020-03-30T05:03:42-06:00",
            "date_utc": "2020-03-30T11:03:42Z",
            "duration": 8513088000000,
            "is_providing_timestamps": true,
            "muxing_application": "libebml v1.3.10 + libmatroska v1.5.2",
            "segment_uid": "d3d29256451c6f2bbfb112baae4aeda2",
            "writing_application": "mkvmerge v44.0.0 ('Domino') 64-bit"
        },
        "recognized": true,
        "supported": true,
        "type": "Matroska"
    },
    "errors": [],
    "file_name": "final_video.mkv",
    "global_tags": [],
    "identification_format_version": 12,
    "track_tags": [],
    "tracks": [
        {
            "codec": "MPEG-4p10/AVC/H.264",
            "id": 0,
            "properties": {
                "codec_id": "V_MPEG4/ISO/AVC",
                "codec_private_data": "01640029ffe1001867640029acd94078065b011000003e90000bb800f183196001000668e938f3c8f0",
                "codec_private_length": 41,
                "default_duration": 41708333,
                "default_track": false,
                "display_dimensions": "1920x800",
                "display_unit": 0,
                "enabled_track": true,
                "forced_track": false,
                "language": "und",
                "minimum_timestamp": 0,
                "number": 1,
                "packetizer": "mpeg4_p10_video",
                "pixel_dimensions": "1920x800",
                "uid": 2105219320381282218
            },
            "type": "video"
        },
        {
            "codec": "SubRip/SRT",
            "id": 1,
            "properties": {
                "codec_id": "S_TEXT/UTF8",
                "codec_private_length": 0,
                "default_track": false,
                "enabled_track": true,
                "encoding": "UTF-8",
                "forced_track": false,
                "language": "eng",
                "minimum_timestamp": 3597000000,
                "number": 2,
                "text_subtitles": true,
                "track_name": "English",
                "uid": 6042543747819283221
            },
            "type": "subtitles"
        },
        {
            "codec": "SubRip/SRT",
            "id": 2,
            "properties": {
                "codec_id": "S_TEXT/UTF8",
                "codec_private_length": 0,
                "default_track": false,
                "enabled_track": true,
                "encoding": "UTF-8",
                "forced_track": false,
                "language": "spa",
                "number": 3,
                "text_subtitles": true,
                "track_name": "Spanish",
                "uid": 18339090840888417108
            },
            "type": "subtitles"
        }
    ],
    "warnings": []
}

Software (please complete the following information):

  • OS: Linux LSTKAG231638 5.5.13-arch1-1 #1 SMP PREEMPT Wed, 25 Mar 2020 16:04:40 +0000 x86_64 GNU/Linux
  • MKVToolNix version: mkvmerge v44.0.0 ('Domino') 64-bit

can't add mkvmerge_path

Describe the bug
I can't import my own mkvmerge_path, whatever path I input, it always says: " FileNotFoundError: mkvmerge is not at the specified path, add it there or change the mkvmerge_path property", I can only use when I add mkvmerge to my environment path

Software (please complete the following information):

  • OS: Debian 10\ Windows 10
  • MKVToolNix version v31.0.0 \v71.1.0

Adding Subtitles removed audio

mkv = MKVFile()
lmkv.add_track(episode_path)
mkv.add_track(subtitle_path)
mkv.mux(output_path)
this causes the output_path to have no audio.

Error in muxing

Hi
I am getting following error on first run when muxing file while second run mux fine. Pls check and suggest how to resolve issue.

Traceback (most recent call last):
File "hotstar.py", line 710, in
mkv.mux(outfile)
File "C:\Users\Adi\AppData\Local\Programs\Python\Python36\lib\site-packages\pymkv\MKVFile.py", line 261, in mux
output_path = expanduser(output_path)
File "C:\Users\Adi\AppData\Local\Programs\Python\Python36\lib\ntpath.py", line 312, in expanduser
path = os.fspath(path)
TypeError: expected str, bytes or os.PathLike object, not _io.BufferedWriter

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.