You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
7.8 KiB

from typing import Optional
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.allowed_passthru_options = AllowedPassthruOptions()
self.__mediainfo: Optional[MediaInfo] = None
self.__audio_track: Optional[AudioTrack] = None
@property
def mediainfo(self):
if not self.__mediainfo:
self.__mediainfo = MediaInfo()
self.__mediainfo.load_file(self.path)
return self.__mediainfo
@property
def audio_track(self):
if not self.__audio_track:
self.__audio_track = AudioTrack(self.mediainfo)
return self.__audio_track
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()
}