mediacurator/mediacurator/library/medialibrary.py

170 lines
6.6 KiB
Python

#!/usr/bin/env python3
'''
This is the container for all the videos found in the folders passed by the user
'''
from pathlib import Path
import sys
from .bcolors import BColors
from .video import Video
class MediaLibrary():
'''
Contains the information and methods of a video file.
'''
size = int()
videos = dict()
directories = list()
inputs = []
filters = []
def __init__(self, files = False, directories = False, inputs = ["any"], filters = []):
'''
This is the library object who holds the information about the workspace and all the videos in it.
'''
if files:
for filepath in files:
self.videos[filepath] = Video(filepath)
elif directories:
self.directories = directories
else:
return
self.inputs = inputs
self.filters = filters
self.load_videos()
self.filter_videos()
def __str__(self):
''' print '''
if self.directories:
text = f"MediaCurator is watching the following directories: "
text += '\n '.join(map(str, self.directories)) + '\n'
text += f"MediaCurator is tracking {len(self.videos)} video files"
return text
def load_videos(self):
'''
Scan folders for video files respecting the inputs requested by the user
Save them to the videos dictionary
'''
print(f"{BColors.OKGREEN}Scanning files in {', '.join(map(str, self.directories))} for videos{BColors.ENDC}")
videolist = []
for directory in self.directories:
path = Path(directory)
if "wmv" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[wW][mM][vV]"))
if "avi" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[aA][vV][iI]"))
if "mkv" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[mM][kK][vV]"))
if "mp4" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[mM][pP]4"))
if "m4v" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[mM]4[vV]"))
if "flv" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[fF][lL][vV]"))
if "mpg" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[mM][pP][gG]"))
if "vid" in self.inputs or "any" in self.inputs or len(self.inputs) < 1:
videolist += list(path.rglob("*.[vV][iI][dD]"))
# Remove folders
videolist_tmp = videolist
videolist = [video for video in videolist_tmp if video.is_file()]
# Map it all to the videos dictionary as initiated Video objects
print(f"{BColors.OKGREEN}Analazing {len(videolist)} videos in {', '.join(map(str, self.directories))}{BColors.ENDC}")
iteration = 0
for video in videolist:
if "-verbose" in sys.argv:
iteration += 1
print(f'{int((iteration / len(videolist )* 100))}% complete', end='\r')
self.videos[video] = Video(video)
def filter_videos(self):
'''
Mark useless videos in the videos dictionary
'''
print(f"{BColors.OKGREEN}Filtering {len(self.videos)} videos for the requested parameters{BColors.ENDC}")
iteration = 0
for filepath in self.videos:
if "-verbose" in sys.argv:
iteration += 1
print(f'{int((iteration / len(self.videos)* 100))}% complete', end='\r')
if len([filtr for filtr in self.filters if filtr in ["old", "mpeg4", "mpeg", "wmv3", "wmv", "h264", "hevc", "x265", "av1"]]) > 0:
useful = False
if "old" in self.filters and self.videos[filepath].codec not in ["hevc", "av1"]:
useful = True
if ("mpeg4" in self.filters or "mpeg" in self.filters) and self.videos[filepath].codec in ["mpeg4", "msmpeg4v3"]:
useful = True
if "mpeg" in self.filters and self.videos[filepath].codec in ["mpeg1video"]:
useful = True
if ("wmv3" in self.filters or "wmv" in self.filters) and self.videos[filepath].codec in ["wmv3"]:
useful = True
if "h264" in self.filters and self.videos[filepath].codec in ["h264"]:
useful = True
if ("hevc" in self.filters or "x265" in self.filters) and self.videos[filepath].codec in ["hevc"]:
useful = True
if "av1" in self.filters and self.videos[filepath].codec in ["av1"]:
useful = True
self.videos[filepath].useful = useful
# keep video if useful and user wants to also filter by selected resolutions
if self.videos[filepath].useful and len([filtr for filtr in self.filters if filtr in ["lowres", "hd", "720p", "1080p", "uhd"]]) > 0:
useful = False
if "lowres" in self.filters and self.videos[filepath].definition in ["sd"]:
useful = True
if "hd" in self.filters and self.videos[filepath].definition in ["720p", "1080p", "uhd"]:
useful = True
if "720p" in self.filters and self.videos[filepath].definition in ["720p"]:
useful = True
if "1080p" in self.filters and self.videos[filepath].definition in ["1080p"]:
useful = True
if "uhd" in self.filters and self.videos[filepath].definition in ["uhd"]:
useful = True
self.videos[filepath].useful = useful
# keep video if useful and user wants to also filter when there is an ffmpeg errors
if self.videos[filepath].useful and len([filtr for filtr in self.filters if filtr in ["fferror"]]) > 0:
useful = False
if self.videos[filepath].error:
useful = True
self.videos[filepath].useful = useful
print(f"{BColors.OKGREEN}Found {len([filepath for filepath in self.videos if self.videos[filepath].useful])} videos for the requested parameters{BColors.ENDC}")