Skip to content

Commit

Permalink
add metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
5hojib committed Jan 1, 2025
1 parent 4ac9876 commit 6ca8906
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 29 deletions.
17 changes: 10 additions & 7 deletions bot/core/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ class Config:
DATABASE_URL = ""
DEFAULT_UPLOAD = "rc"
DOWNLOAD_DIR = "/usr/src/app/downloads/"
DELETE_LINKS = False
EXTENSION_FILTER = ""
FSUB_IDS = ""
FFMPEG_CMDS = {}
FILELION_API = ""
GDRIVE_ID = ""
Expand All @@ -30,8 +28,6 @@ class Config:
MEGA_PASSWORD = ""
NAME_SUBSTITUTE = ""
OWNER_ID = 0
PAID_CHANNEL_ID = 0
PAID_CHANNEL_LINK = ""
QUEUE_ALL = 0
QUEUE_DOWNLOAD = 0
QUEUE_UPLOAD = 0
Expand All @@ -45,7 +41,6 @@ class Config:
RSS_DELAY = 600
SEARCH_API_LINK = ""
SEARCH_LIMIT = 0
SET_COMMANDS = True
SEARCH_PLUGINS: ClassVar[list[str]] = []
STOP_DUPLICATE = False
STREAMWISH_API = ""
Expand All @@ -54,15 +49,23 @@ class Config:
TELEGRAM_HASH = ""
THUMBNAIL_LAYOUT = ""
TORRENT_TIMEOUT = 0
TOKEN_TIMEOUT = 0
USER_TRANSMISSION = False
UPSTREAM_REPO = ""
UPSTREAM_BRANCH = "main"
USER_SESSION_STRING = ""
USE_SERVICE_ACCOUNTS = False
WEB_PINCODE = False
YT_DLP_OPTIONS = ""


# INKYPINKY
METADATA_KEY = ""
SET_COMMANDS = True
TOKEN_TIMEOUT = 0
PAID_CHANNEL_ID = 0
PAID_CHANNEL_LINK = ""
DELETE_LINKS = False
FSUB_IDS = ""

@classmethod
def get(cls, key):
if hasattr(cls, key):
Expand Down
31 changes: 19 additions & 12 deletions bot/helper/aeon_utils/metadata_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
from bot import LOGGER


async def change_metadata(file, key):
LOGGER.info(f"Starting metadata modification for file: {file}")
temp_file = f"{file}.temp.mkv"

async def get_streams(file):
cmd = [
"ffprobe",
"-hide_banner",
Expand All @@ -25,26 +22,36 @@ async def change_metadata(file, key):

if process.returncode != 0:
LOGGER.error(f"Error getting stream info: {stderr.decode().strip()}")
return
return None

try:
streams = json.loads(stdout)["streams"]
return json.loads(stdout)["streams"]
except KeyError:
LOGGER.error(
f"No streams found in the ffprobe output: {stdout.decode().strip()}",
)
LOGGER.error(f"No streams found in the ffprobe output: {stdout.decode().strip()}")
return None


async def change_metadata(file, key):
LOGGER.info(f"Starting metadata modification for file: {file}")
temp_file = f"{file}.temp.mkv"

streams = await get_streams(file)
if not streams:
return

languages = {}
for stream in streams:
stream_index = stream["index"]
stream_type = stream["codec_type"]
if "tags" in stream and "language" in stream["tags"]:
languages[stream_index] = stream["tags"]["language"]

cmd = [
"xtra",
"-y",
"-hide_banner",
"-loglevel",
"error",
"-progress",
"pipe:1",
"-i",
file,
"-map_metadata",
Expand Down Expand Up @@ -175,4 +182,4 @@ async def add_attachment(file, attachment_path):

os.replace(temp_file, file)
LOGGER.info(f"Photo attachment added successfully to file: {file}")
return
return
142 changes: 142 additions & 0 deletions bot/helper/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,13 @@
create_thumb,
get_document_type,
run_ffmpeg_cmd,
run_metadata_cmd,
split_file,
take_ss,
is_mkv,
)
from bot.helper.aeon_utils.metadata_editor import change_metadata, get_streams

from .mirror_leech_utils.gdrive_utils.list import GoogleDriveList
from .mirror_leech_utils.rclone_utils.list import RcloneList
from .mirror_leech_utils.status_utils.ffmpeg_status import FFmpegStatus
Expand Down Expand Up @@ -1312,3 +1316,141 @@ async def proceed_ffmpeg(self, dl_path, gid):
if checked:
cpu_eater_lock.release()
return dl_path

async def proceed_metadata(self, up_dir, gid):
key = self.metadata
async with task_dict_lock:
task_dict[self.mid] = FFmpegStatus(self, gid, "Metadata")
checked = False

async def process_file(file_path, key):
"""Processes a single file to update metadata."""
temp_file = f"{file_path}.temp.mkv"
streams = await get_streams(file_path)
if not streams:
return ""

languages = {
stream["index"]: stream["tags"]["language"]
for stream in streams
if "tags" in stream and "language" in stream["tags"]
}

cmd = [
"xtra",
"-hide_banner",
"-loglevel",
"error",
"-progress",
"pipe:1",
"-i",
file_path,
"-map_metadata",
"-1",
"-c",
"copy",
"-metadata:s:v:0",
f"title={key}",
"-metadata",
f"title={key}",
]

audio_index = 0
subtitle_index = 0
first_video = False

for stream in streams:
stream_index = stream["index"]
stream_type = stream["codec_type"]

if stream_type == "video":
if not first_video:
cmd.extend(["-map", f"0:{stream_index}"])
first_video = True
cmd.extend([f"-metadata:s:v:{stream_index}", f"title={key}"])
if stream_index in languages:
cmd.extend(
[
f"-metadata:s:v:{stream_index}",
f"language={languages[stream_index]}",
]
)
elif stream_type == "audio":
cmd.extend(
[
"-map",
f"0:{stream_index}",
f"-metadata:s:a:{audio_index}",
f"title={key}",
]
)
if stream_index in languages:
cmd.extend(
[
f"-metadata:s:a:{audio_index}",
f"language={languages[stream_index]}",
]
)
audio_index += 1
elif stream_type == "subtitle":
codec_name = stream.get("codec_name", "unknown")
if codec_name in ["webvtt", "unknown"]:
LOGGER.warning(
f"Skipping unsupported subtitle metadata modification: {codec_name} for stream {stream_index}"
)
else:
cmd.extend(
[
"-map",
f"0:{stream_index}",
f"-metadata:s:s:{subtitle_index}",
f"title={key}",
]
)
if stream_index in languages:
cmd.extend(
[
f"-metadata:s:s:{subtitle_index}",
f"language={languages[stream_index]}",
]
)
subtitle_index += 1
else:
cmd.extend(["-map", f"0:{stream_index}"])

cmd.append(temp_file)
return cmd, temp_file

async def process_directory(directory, key):
"""Processes all MKV files in a directory."""
for dirpath, _, files in await sync_to_async(walk, directory, topdown=False):
for file_ in files:
file_path = ospath.join(dirpath, file_)
if is_mkv(file_path):
cmd, temp_file = await process_file(file_path, key)
if not cmd:
return ""
if not checked:
await cpu_eater_lock.acquire()
if self.isCancelled:
cpu_eater_lock.release()
return ""
await run_metadata_cmd(self, cmd)
os.replace(temp_file, file_path)


if self.is_file:
if is_mkv(up_dir):
cmd, temp_file = await process_file(up_dir, key)
if cmd:
checked = True
await cpu_eater_lock.acquire()
await run_metadata_cmd(self, cmd)
os.replace(temp_file, up_dir)
cpu_eater_lock.release()
else:
await process_directory(up_dir, key)

if checked:
cpu_eater_lock.release()
return up_dir
52 changes: 48 additions & 4 deletions bot/helper/ext_utils/media_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,10 +766,10 @@ async def create_sample_video(listener, video_file, sample_duration, part_durati
return None


async def run_ffmpeg_cmd(listener, ffmpeg, path):
async def run_ffmpeg_cmd(listener, cmd, path):
base_name, ext = ospath.splitext(path)
dir, base_name = base_name.rsplit("/", 1)
output_file = ffmpeg[-1]
output_file = cmd[-1]
if output_file != "mltb" and output_file.startswith("mltb"):
oext = ospath.splitext(output_file)[-1]
if ext == oext:
Expand All @@ -779,12 +779,12 @@ async def run_ffmpeg_cmd(listener, ffmpeg, path):
else:
base_name = f"ffmpeg.{base_name}"
output = f"{dir}/{base_name}{ext}"
ffmpeg[-1] = output
cmd[-1] = output
if listener.is_cancelled:
return False
async with listener.subprocess_lock:
listener.subproc = await create_subprocess_exec(
*ffmpeg, stdout=PIPE, stderr=PIPE
*cmd, stdout=PIPE, stderr=PIPE
)
code = await listener.subproc.wait()
async with listener.subprocess_lock:
Expand All @@ -805,3 +805,47 @@ async def run_ffmpeg_cmd(listener, ffmpeg, path):
if await aiopath.exists(output):
await remove(output)
return False


async def run_metadata_cmd(listener, cmd):
#base_name, ext = ospath.splitext(path)
#dir, base_name = base_name.rsplit("/", 1)
#output_file = cmd[-1]
#if output_file != "mltb" and output_file.startswith("mltb"):
# oext = ospath.splitext(output_file)[-1]
# if ext == oext:
# base_name = f"ffmpeg.{base_name}"
# else:
# ext = oext
#else:
# base_name = f"ffmpeg.{base_name}"
# output = f"{dir}/{base_name}{ext}"
# cmd[-1] = output
if listener.is_cancelled:
return False
async with listener.subprocess_lock:
listener.subproc = await create_subprocess_exec(
*cmd, stdout=PIPE, stderr=PIPE
)
code = await listener.subproc.wait()
async with listener.subprocess_lock:
if listener.is_cancelled:
return False
if code == 0:
return output
if code == -9:
listener.is_cancelled = True
return False
try:
stderr = (await listener.subproc.stderr.read()).decode().strip()
except Exception:
stderr = "Unable to decode the error!"
LOGGER.error(
f"{stderr}. Something went wrong while running metadata cmd, mostly file requires different/specific arguments.",
)
# if await aiopath.exists(output):
# await remove(output)
return False

def is_mkv(file):
return file.lower().endswith(".mkv")
1 change: 1 addition & 0 deletions bot/helper/ext_utils/status_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class MirrorStatus:
STATUS_SAMVID = "SamVid"
STATUS_CONVERT = "Convert"
STATUS_FFMPEG = "FFmpeg"
STATUS_METADATA = "Metadata"


STATUSES = {
Expand Down
4 changes: 3 additions & 1 deletion bot/helper/mirror_leech_utils/status_utils/ffmpeg_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def eta(self):
self.listener.subsize - self._processed_bytes
) / self._speed_raw
return get_readable_time(seconds)
except:
except Exception:
return "-"

def status(self):
Expand All @@ -82,6 +82,8 @@ def status(self):
return MirrorStatus.STATUS_SPLIT
if self.cstatus == "Sample Video":
return MirrorStatus.STATUS_SAMVID
if self.cstatus == "Metadata":
return MirrorStatus.STATUS_METADATA
return MirrorStatus.STATUS_FFMPEG

def task(self):
Expand Down
Loading

0 comments on commit 6ca8906

Please sign in to comment.