from minfo import MediaInfo from pathlib import Path class Configuration: def __init__(self): pass def as_dict(self): return { "IsDvdNavDisabled": False, "EnableQuickSyncDecoding": False, "UseQSVDecodeForNonQSVEnc": False, "ScalingMode": 0, "PreviewScanCount": 10, "Verbosity": 1, "MinScanDuration": 10, "SaveLogToCopyDirectory": False, "SaveLogWithVideo": False, "SaveLogCopyDirectory": "", "RemoteServiceEnabled": False, "RemoteServicePort": 0, "EnableVceEncoder": True, "EnableNvencEncoder": False, "EnableQsvEncoder": False } class Statistics: def __init__(self): pass def as_dict(self): return { "StartTime": "0001-01-01T00:00:00", "StartTimeDisplay": "Not Available", "EndTime": "0001-01-01T00:00:00", "EndTimeDisplay": "", "PausedDuration": "00:00:00", "PausedDisplay": "", "Duration": "00:00:00", "DurationDisplay": "", "FinalFileSizeInMegaBytes": 0, "FileSizeDisplay": "", "IsNotifying": True } class AllowedPassthruOptions: def __init__(self): pass def as_dict(self): return { "AudioAllowAACPass": True, "AudioAllowAC3Pass": True, "AudioAllowDTSHDPass": True, "AudioAllowDTSPass": True, "AudioAllowMP3Pass": True, "AudioAllowTrueHDPass": True, "AudioAllowFlacPass": True, "AudioAllowEAC3Pass": True, "AudioEncoderFallback": 5, "AllowedPassthruOptions": [ 13, 8, 11, 10, 14, 12, 18, 9 ] } class AudioTrack: def __init__(self, minfo: MediaInfo): self.minfo = minfo def as_dict(self): return { "DRC": 0.0, "Gain": 0, "Encoder": 7, "SampleRate": 0.0, "EncoderRateType": 0, "Bitrate": 160, "Quality": -1.0, "ScannedTrack": { "TrackNumber": 1, "Language": self.minfo.tracks[0].language, # "LanguageCode": "und", "Name": self.minfo.tracks[0].name, #"Codec": 65536, # aac is 65536 # mp3 is 524288 #"SampleRate": 32000, #"Bitrate": 32002, #"ChannelLayout": 4 }, "IsNotifying": True } class Chapters: def __init__(self, minfo: MediaInfo): self.minfo = minfo def as_dict(self): return [ { "ChapterNumber": index + 1, "Duration": c.duration, # self.mediainfo.duration, "ChapterName": c.name, # "Chapter 1", "IsNotifying": True } for index, c in enumerate(self.minfo.menu.items) ] class Task: def __init__(self, path: Path, destination: Path): self.path = path self.destination = destination / (path.name.rsplit(".", 1)[0] + '.m4v') self.mediainfo = MediaInfo(self.path) self.allowed_passthru_options = AllowedPassthruOptions() self.audio_track = AudioTrack(self.mediainfo) def as_dict(self): return { "Source": str(self.path), "Title": 1, "Angle": 1, "PointToPointMode": 0, "StartPoint": 1, "EndPoint": len(self.mediainfo.menu.items), "Destination": str(self.destination), "OutputFormat": 0, "OptimizeMP4": False, "IPod5GSupport": False, "AlignAVStart": True, "Width": self.mediainfo.resolution.width, "Height": self.mediainfo.resolution.height, "Cropping": { "Top": 0, "Bottom": 0, "Left": 0, "Right": 0 }, "HasCropping": False, "Anamorphic": 4, "DisplayWidth": self.mediainfo.display_width, "KeepDisplayAspect": self.mediainfo.keep_display_aspect, "PixelAspectX": int(self.mediainfo.pixel_aspect_ratio.x), "PixelAspectY": int(self.mediainfo.pixel_aspect_ratio.y), "Modulus": 2, "DeinterlaceFilter": 2, "DeinterlacePreset": { "Name": "Default", "ShortName": "default" }, "CombDetect": 2, "CustomDeinterlaceSettings": "", "CustomCombDetect": "", "Detelecine": 0, "CustomDetelecine": "", "Denoise": 0, "DenoisePreset": 5, "DenoiseTune": 0, "CustomDenoise": "", "Grayscale": False, "Rotation": 0, "FlipVideo": False, "Sharpen": 0, "SharpenPreset": { "DisplayName": "Medium", "Key": "medium" }, "SharpenTune": { "DisplayName": "None", "Key": "none" }, "SharpenCustom": "", "DeblockPreset": { "DisplayName": "Off", "Key": "off" }, "DeblockTune": { "DisplayName": "Medium (8x8)", "Key": "medium" }, "CustomDeblock": "strength=strong:thresh=20:blocksize=8", "VideoEncodeRateType": 1, "VideoEncoder": 13, "VideoProfile": { "DisplayName": "Main", "ShortName": "main" }, "VideoLevel": { "DisplayName": "Auto", "ShortName": "auto" }, "VideoPreset": { "DisplayName": "Quality", "ShortName": "quality" }, "VideoTunes": [], "ExtraAdvancedArguments": "", "FramerateMode": 1, "Quality": 22.0, "VideoBitrate": self.mediainfo.output_bitrate, "TwoPass": False, "TurboFirstPass": False, "Framerate": self.mediainfo.framerate, "AudioTracks": [ self.audio_track.as_dict() ], "AllowedPassthruOptions": self.allowed_passthru_options.as_dict(), "SubtitleTracks": [], "IncludeChapterMarkers": len(self.mediainfo.menu.items) > 1, "ChapterNames": Chapters(self.mediainfo).as_dict(), "MetaData": {}, "IsPreviewEncode": False } class QueueItem: def __init__(self, path: Path, destination: Path): self.path = path self.task = Task(path, destination) self.configuration = Configuration() self.statistics = Statistics() def as_dict(self): return { "ScannedSourcePath": str(self.path), "Status": 0, "Task": self.task.as_dict(), "Configuration": self.configuration.as_dict(), "Statistics": self.statistics.as_dict() }