RenameBot / plugins /audio_features.py
Thaimozhi
Process ahndling Fix
04eb236
Raw History Blame Contribute Delete
8.67 kB
import os
import time
import asyncio
from pyrogram import Client, filters, ContinuePropagation
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
from helper.utils import progress_for_pyrogram
from plugins.file_rename import extract_season_episode, extract_quality
# Dictionary to store ongoing audio operations
audio_ops = {}
@Client.on_message(filters.private & filters.command("audio") & filters.reply)
async def audio_command(client, message):
replied = message.reply_to_message
if not (replied.video or replied.document):
return await message.reply_text("Please reply to a video or document file with /audio")
file_id = replied.video.file_id if replied.video else replied.document.file_id
# Store message id for callback
keyboard = InlineKeyboardMarkup([
[
InlineKeyboardButton("πŸ”‡ Remove Audio", callback_data=f"aud_rm_{replied.id}"),
InlineKeyboardButton("πŸ”€ Reorder Audio", callback_data=f"aud_re_{replied.id}")
],
[
InlineKeyboardButton("βš™οΈ Set Default Audio", callback_data=f"aud_def_{replied.id}")
]
])
await message.reply_text(
"**Audio Management Options:**\n\n"
"Choose what you want to do with the audio tracks of this file.\n"
"*(Note: You will be asked to enter track numbers. Track 1 = 0, Track 2 = 1)*",
reply_markup=keyboard
)
@Client.on_callback_query(filters.regex(r"^aud_"))
async def audio_callback(client, query: CallbackQuery):
data = query.data.split("_")
action = data[1] # rm, re, def
msg_id = int(data[2])
user_id = query.from_user.id
if action == "rm":
text = "Reply to this message with the audio track number you want to REMOVE.\n\nExample: `1` (removes 2nd track)"
elif action == "re":
text = "Reply to this message with the new order of tracks (comma separated).\n\nExample: `1,0` (swaps track 1 and 2)"
elif action == "def":
text = "Reply to this message with the track number you want to set as DEFAULT.\n\nExample: `1` (sets 2nd track as default)"
prompt = await query.message.edit_text(text)
# Save state
audio_ops[user_id] = {
"action": action,
"msg_id": msg_id,
"prompt_id": prompt.id
}
@Client.on_message(filters.private & filters.reply)
async def process_audio_input(client, message):
user_id = message.from_user.id
if user_id not in audio_ops:
raise ContinuePropagation
op = audio_ops[user_id]
if message.reply_to_message.id != op["prompt_id"]:
raise ContinuePropagation
action = op["action"]
msg_id = op["msg_id"]
user_input = message.text.strip()
del audio_ops[user_id] # Clear state
target_msg = await client.get_messages(message.chat.id, msg_id)
if not target_msg:
return await message.reply_text("Original message not found.")
status = await message.reply_text("πŸ“₯ Downloading file for audio processing...")
try:
# Download
file_name = target_msg.video.file_name if target_msg.video else target_msg.document.file_name
if not file_name:
file_name = "downloaded_video.mkv"
download_path = f"downloads/{user_id}_{file_name}"
start_time = time.time()
file_path = await client.download_media(
target_msg,
file_name=download_path,
progress=progress_for_pyrogram,
progress_args=("Downloading...", status, start_time)
)
await status.edit("βš™οΈ Processing audio with FFmpeg... This may take a while.")
output_path = f"downloads/processed_{user_id}_{file_name}"
# Build FFmpeg command based on action
if action == "rm":
track_idx = int(user_input)
# Remove specific audio track (negative mapping)
cmd = f'ffmpeg -i "{file_path}" -map 0 -map -0:a:{track_idx} -c copy "{output_path}" -y'
elif action == "re":
tracks = user_input.split(",")
# Reorder: map video, then map audio tracks in specified order
# Example: ffmpeg -i in.mkv -map 0:v -map 0:a:1 -map 0:a:0 -c copy out.mkv
maps = "-map 0:v " + " ".join([f"-map 0:a:{t.strip()}" for t in tracks])
# Also map subtitles if any
maps += " -map 0:s? "
cmd = f'ffmpeg -i "{file_path}" {maps} -c copy "{output_path}" -y'
elif action == "def":
track_idx = int(user_input)
# Set default track disposition
cmd = f'ffmpeg -i "{file_path}" -map 0 -c copy -disposition:a:0 0 -disposition:a:{track_idx} default "{output_path}" -y'
# Run FFmpeg
process = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await process.communicate()
if process.returncode != 0:
await status.edit(f"❌ FFmpeg error: \n```\n{stderr.decode()[:500]}\n```")
return
await status.edit("πŸ“€ Uploading processed file...")
# Upload
start_time = time.time()
await client.send_document(
chat_id=message.chat.id,
document=output_path,
caption=f"Processed: {file_name}\nAction: {action}",
file_name=file_name,
progress=progress_for_pyrogram,
progress_args=("Uploading...", status, start_time)
)
await status.delete()
# Cleanup
os.remove(file_path)
os.remove(output_path)
except ValueError:
await status.edit("❌ Invalid input! Please enter numbers only.")
except Exception as e:
await status.edit(f"❌ Error: {str(e)}")
@Client.on_message(filters.private & filters.command(["setaudioorder", "set_auto_audio_order"]))
async def set_audio_order(client, message):
if len(message.command) < 2:
return await message.reply_text("Usage: /set_auto_audio_order 1,0,2\nTo reset, use /reset_auto_audio_order")
order = message.command[1]
from helper.database import codeflixbots
await codeflixbots.set_audio_order(message.from_user.id, order)
await message.reply_text(f"βœ… Auto Uploader Audio order saved as `{order}`. It will be applied automatically to auto uploader jobs.")
@Client.on_message(filters.private & filters.command(["resetaudioorder", "reset_auto_audio_order"]))
async def reset_audio_order(client, message):
from helper.database import codeflixbots
await codeflixbots.set_audio_order(message.from_user.id, None)
await message.reply_text("βœ… Auto Uploader Audio order reset to default.\n\n")
@Client.on_message(filters.private & filters.command(["set_leech_audio_order"]))
async def set_leech_audio_order(client, message):
if len(message.command) < 2:
return await message.reply_text("Usage: /set_leech_audio_order 1,0,2\nTo reset, use /reset_leech_audio_order")
order = message.command[1]
from helper.database import codeflixbots
await codeflixbots.set_merge_audio_order(message.from_user.id, order)
await message.reply_text(f"βœ… Leech/Rename Audio order saved as `{order}`. It will be applied automatically for normal files.")
@Client.on_message(filters.private & filters.command(["reset_leech_audio_order"]))
async def reset_leech_audio_order(client, message):
from helper.database import codeflixbots
await codeflixbots.set_merge_audio_order(message.from_user.id, None)
await message.reply_text("βœ… Leech/Rename Audio order reset to default.")
@Client.on_message(filters.private & filters.command("setdefaultaudio"))
async def set_default_audio(client, message):
if len(message.command) < 2:
return await message.reply_text("Usage: /setdefaultaudio 0\nTo reset, use /resetdefaultaudio")
default_track = message.command[1]
from helper.database import codeflixbots
await codeflixbots.set_audio_default(message.from_user.id, default_track)
await message.reply_text(f"βœ… Default audio track set to `{default_track}`. It will be applied automatically.")
@Client.on_message(filters.private & filters.command("resetdefaultaudio"))
async def reset_default_audio(client, message):
from helper.database import codeflixbots
await codeflixbots.set_audio_default(message.from_user.id, None)
await message.reply_text("βœ… Default audio track reset.")