video-stream/bot/videoplayer.py

328 lines
12 KiB
Python
Raw Normal View History

2021-09-09 01:18:24 +00:00
import os
import asyncio
import subprocess
from pytgcalls import idle
2021-09-13 09:51:14 +00:00
from pytgcalls.pytgcalls import PyTgCalls
from pytgcalls import StreamType
from pytgcalls.types import Update
2021-09-13 02:47:30 +00:00
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
2021-09-09 01:18:24 +00:00
from pyrogram import Client, filters
from pyrogram.types import Message
2021-09-12 04:35:53 +00:00
from config import Veez
2021-09-09 01:18:24 +00:00
from helpers.decorators import authorized_users_only
from helpers.filters import command
2021-09-13 18:53:29 +00:00
from helpers.loggings import LOG
2021-09-09 20:54:36 +00:00
from youtube_dl import YoutubeDL
from youtube_dl.utils import ExtractorError
2021-09-13 09:51:14 +00:00
from pytgcalls.types.input_stream import (
VideoParameters,
AudioParameters,
InputAudioStream,
InputVideoStream
)
2021-09-09 01:18:24 +00:00
2021-09-09 20:54:36 +00:00
SIGINT: int = 2
2021-09-09 01:18:24 +00:00
2021-09-12 04:35:53 +00:00
app = Client(Veez.SESSION_NAME, Veez.API_ID, Veez.API_HASH)
call_py = PyTgCalls(app)
2021-09-10 09:10:17 +00:00
FFMPEG_PROCESS = {}
2021-09-09 01:18:24 +00:00
2021-09-13 15:16:53 +00:00
def convert_seconds(seconds: int) -> str:
seconds = seconds % (24 * 3600)
seconds %= 3600
minutes = seconds // 60
seconds %= 60
return "%02d:%02d" % (minutes, seconds)
def raw_converter(dl, song, video):
2021-09-09 20:54:36 +00:00
return subprocess.Popen(
2021-09-12 01:48:56 +00:00
['ffmpeg', '-i', dl, '-f', 's16le', '-ac', '1', '-ar', '48000', song, '-y', '-f', 'rawvideo', '-r', '20', '-pix_fmt', 'yuv420p', '-vf', 'scale=854:480', video, '-y'],
stdin=None,
stdout=None,
stderr=None,
cwd=None,
)
2021-09-09 01:18:24 +00:00
async def leave_call(chat_id: int):
2021-09-13 08:16:02 +00:00
process = FFMPEG_PROCESS.get(chat_id)
if process:
try:
process.send_signal(SIGINT)
await asyncio.sleep(3)
except Exception as e:
print(e)
pass
try:
await call_py.leave_group_call(chat_id)
except Exception as e:
print(f"🚫 error - {e}")
2021-09-09 20:54:36 +00:00
def youtube(url: str):
try:
2021-09-10 22:16:30 +00:00
params = {"format": "best[height=?480]/best", "noplaylist": True}
2021-09-09 20:54:36 +00:00
yt = YoutubeDL(params)
info = yt.extract_info(url, download=False)
2021-09-12 22:49:35 +00:00
return info['url'], info['title'], info['duration']
except ExtractorError:
2021-09-12 22:49:35 +00:00
return None, None
2021-09-09 20:54:36 +00:00
except Exception:
2021-09-12 22:49:35 +00:00
return None, None
2021-09-09 20:54:36 +00:00
2021-09-09 01:18:24 +00:00
2021-09-12 04:35:53 +00:00
@Client.on_message(command(["vplay", f"vplay@{Veez.BOT_USERNAME}"]) & filters.group & ~filters.edited)
2021-09-09 01:18:24 +00:00
@authorized_users_only
async def startvideo(client, m: Message):
2021-09-13 02:47:30 +00:00
keyboard = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="✨ ɢʀᴏᴜᴘ",
url="https://t.me/VeezSupportGroup"),
InlineKeyboardButton(
text="🌻 ᴄʜᴀɴɴᴇʟ",
url="https://t.me/levinachannel")
]
]
)
2021-09-09 01:18:24 +00:00
replied = m.reply_to_message
if not replied:
if len(m.command) < 2:
2021-09-13 08:16:02 +00:00
await m.reply("💡 **reply to video or provide youtube/live video url to start video streaming**")
2021-09-09 01:18:24 +00:00
else:
livelink = m.text.split(None, 1)[1]
chat_id = m.chat.id
2021-09-09 20:54:36 +00:00
try:
livelink, title, duration = await asyncio.wait_for(
2021-09-09 20:54:36 +00:00
app.loop.run_in_executor(
None,
lambda : youtube(livelink)
),
2021-09-13 14:04:09 +00:00
timeout=None
2021-09-09 20:54:36 +00:00
)
except asyncio.TimeoutError:
await m.reply("TimeoutError: process is taking unexpected time")
return
if not livelink:
await m.reply("failed to get video data")
return
process = raw_converter(livelink, f'audio{chat_id}.raw', f'video{chat_id}.raw')
2021-09-10 09:10:17 +00:00
FFMPEG_PROCESS[chat_id] = process
msg = await m.reply("🔁 **starting video streaming...**")
2021-09-10 06:56:49 +00:00
await asyncio.sleep(10)
try:
audio_file = f'audio{chat_id}.raw'
video_file = f'video{chat_id}.raw'
while not os.path.exists(audio_file) or \
not os.path.exists(video_file):
await asyncio.sleep(2)
await call_py.join_group_call(
chat_id,
InputAudioStream(
audio_file,
AudioParameters(
bitrate=48000,
),
),
InputVideoStream(
video_file,
VideoParameters(
2021-09-10 22:16:30 +00:00
width=854,
height=480,
frame_rate=20,
),
),
stream_type=StreamType().local_stream,
)
2021-09-13 06:38:04 +00:00
await m.reply_photo(
2021-09-13 02:47:30 +00:00
photo="https://telegra.ph/file/422650a849a8d6831bde8.png",
reply_markup=keyboard,
2021-09-13 15:16:53 +00:00
caption=f"💡 **video streaming started!**\n\n🏷 **Name:** {title}\n⏱ **Duration:** `{convert_seconds(duration)}`\n\n» **join to video chat on the top to watch the video.**")
2021-09-13 06:38:04 +00:00
return await msg.delete()
await idle()
except Exception as e:
await msg.edit(f"🚫 **error** | `{e}`")
2021-09-09 01:18:24 +00:00
elif replied.video or replied.document:
msg = await m.reply("📥 downloading video...")
video = await client.download_media(m.reply_to_message)
chat_id = m.chat.id
2021-09-13 06:38:04 +00:00
await msg.edit("🔁 **preparing video...**")
os.system(f"ffmpeg -i '{video}' -f s16le -ac 1 -ar 48000 'audio{chat_id}.raw' -y -f rawvideo -r 20 -pix_fmt yuv420p -vf scale=640:360 'video{chat_id}.raw' -y")
2021-09-09 01:18:24 +00:00
try:
audio_file = f'audio{chat_id}.raw'
video_file = f'video{chat_id}.raw'
while not os.path.exists(audio_file) or \
not os.path.exists(video_file):
await asyncio.sleep(2)
await call_py.join_group_call(
chat_id,
InputAudioStream(
audio_file,
AudioParameters(
bitrate=48000,
),
),
InputVideoStream(
video_file,
VideoParameters(
width=640,
height=360,
frame_rate=20,
),
),
stream_type=StreamType().local_stream,
)
2021-09-13 06:38:04 +00:00
await m.reply_photo(
2021-09-13 02:47:30 +00:00
photo="https://telegra.ph/file/dc90e91cc77e68568e7b4.png",
reply_markup=keyboard,
2021-09-13 06:38:04 +00:00
caption=f"💡 **video streaming started !**\n\n» **join to video chat on the top to watch the video.**")
return await msg.delete()
2021-09-13 02:56:52 +00:00
except Exception as e:
2021-09-13 06:38:04 +00:00
await msg.edit(f"🚫 **error** | `{e}`")
await idle()
2021-09-09 01:18:24 +00:00
else:
await m.reply("💭 please reply to video or video file to stream")
2021-09-12 04:35:53 +00:00
@Client.on_message(command(["vstop", f"vstop@{Veez.BOT_USERNAME}"]) & filters.group & ~filters.edited)
2021-09-09 01:18:24 +00:00
@authorized_users_only
async def stopvideo(client, m: Message):
chat_id = m.chat.id
try:
2021-09-10 09:10:17 +00:00
process = FFMPEG_PROCESS.get(chat_id)
if process:
try:
process.send_signal(SIGINT)
await asyncio.sleep(3)
except Exception as e:
print(e)
pass
await call_py.leave_group_call(chat_id)
2021-09-12 07:53:59 +00:00
await m.reply("✅ **successfully left vc !**")
2021-09-09 01:18:24 +00:00
except Exception as e:
await m.reply(f"🚫 **error** | `{e}`")
2021-09-12 23:22:13 +00:00
@call_py.on_stream_end()
async def handler(client: PyTgCalls, update: Update):
2021-09-13 18:53:29 +00:00
LOG.info(f"called ended stream")
2021-09-13 09:51:14 +00:00
chat_id = update.chat_id
2021-09-13 09:54:02 +00:00
await call_py.leave_group_call(chat_id)
2021-09-13 08:16:02 +00:00
@Client.on_message(command(["cplay", f"cplay@{Veez.BOT_USERNAME}"]) & filters.group & ~filters.edited)
@authorized_users_only
async def chstream(client, m: Message):
replied = m.reply_to_message
if not replied:
if len(m.command) < 2:
await m.reply("💡 **reply to video or provide youtube/live video url to start video streaming**")
else:
livelink = m.text.split(None, 1)[1]
2021-09-13 14:53:50 +00:00
chat_id = Veez.CHANNEL
2021-09-13 08:16:02 +00:00
try:
livelink = await asyncio.wait_for(
app.loop.run_in_executor(
None,
lambda : youtube(livelink)
),
timeout=None
)
except asyncio.TimeoutError:
await m.reply("TimeoutError: process is taking unexpected time")
return
if not livelink:
await m.reply("failed to get video data")
return
process = raw_converter(livelink, f'audio{chat_id}.raw', f'video{chat_id}.raw')
FFMPEG_PROCESS[chat_id] = process
msg = await m.reply("🔁 **starting video streaming...**")
await asyncio.sleep(10)
try:
audio_file = f'audio{chat_id}.raw'
video_file = f'video{chat_id}.raw'
while not os.path.exists(audio_file) or \
not os.path.exists(video_file):
await asyncio.sleep(2)
await call_py.join_group_call(
chat_id,
InputAudioStream(
audio_file,
AudioParameters(
bitrate=48000,
),
),
InputVideoStream(
video_file,
VideoParameters(
width=854,
height=480,
frame_rate=20,
),
),
stream_type=StreamType().local_stream,
)
await msg.edit("💡 **video streaming channel started !**")
await idle()
except Exception as e:
await msg.edit(f"🚫 **error** - `{e}`")
elif replied.video or replied.document:
msg = await m.reply("📥 **downloading video...**")
video = await client.download_media(m.reply_to_message)
2021-09-13 14:53:50 +00:00
chat_id = Veez.CHANNEL
2021-09-13 08:16:02 +00:00
await msg.edit("🔁 **preparing video...**")
os.system(f"ffmpeg -i '{video}' -f s16le -ac 1 -ar 48000 'audio{chat_id}.raw' -y -f rawvideo -r 20 -pix_fmt yuv420p -vf scale=640:360 'video{chat_id}.raw' -y")
try:
audio_file = f'audio{chat_id}.raw'
video_file = f'video{chat_id}.raw'
while not os.path.exists(audio_file) or \
not os.path.exists(video_file):
await asyncio.sleep(2)
await call_py.join_group_call(
chat_id,
InputAudioStream(
audio_file,
AudioParameters(
bitrate=48000,
),
),
InputVideoStream(
video_file,
VideoParameters(
width=640,
height=360,
frame_rate=20,
),
),
stream_type=StreamType().local_stream,
)
await msg.edit("💡 **video streaming channel started !**")
except Exception as e:
await msg.edit(f"🚫 **error** - `{e}`")
await idle()
else:
await m.reply("💭 **please reply to video or video file to stream**")
@Client.on_message(command(["cstop", f"cstop@{Veez.BOT_USERNAME}"]) & filters.group & ~filters.edited)
@authorized_users_only
async def chstopvideo(client, m: Message):
2021-09-13 14:53:50 +00:00
chat_id = Veez.CHANNEL
2021-09-13 08:16:02 +00:00
try:
process = FFMPEG_PROCESS.get(chat_id)
if process:
try:
process.send_signal(SIGINT)
await asyncio.sleep(3)
except Exception as e:
print(e)
2021-09-13 14:04:09 +00:00
pass
2021-09-13 08:16:02 +00:00
await call_py.leave_group_call(chat_id)
await m.reply("✅ **video streaming channel ended**")
except Exception as e:
await m.reply(f"🚫 **error** - `{e}`")