2021-09-13 23:09:26 +00:00
# Copyright (C) 2021 By VeezMusicProject
2021-09-09 01:18:24 +00:00
import os
import asyncio
2021-09-09 03:00:36 +00:00
import subprocess
from pytgcalls import idle
2021-09-13 09:51:14 +00:00
from pytgcalls . pytgcalls import PyTgCalls
2021-09-09 03:00:36 +00:00
from pytgcalls import StreamType
2021-09-12 22:35:49 +00:00
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 )
2021-09-09 03:00:36 +00:00
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 )
2021-09-09 03:00:36 +00:00
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 ' ] ,
2021-09-09 03:00:36 +00:00
stdin = None ,
stdout = None ,
stderr = None ,
cwd = None ,
)
2021-09-09 01:18:24 +00:00
2021-09-12 22:35:49 +00:00
async def leave_call ( chat_id : int ) :
2021-09-13 08:16:02 +00:00
process = FFMPEG_PROCESS . get ( chat_id )
2021-09-12 22:35:49 +00:00
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 ' ]
2021-09-12 22:47:27 +00:00
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
2021-09-09 03:00:36 +00:00
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 :
2021-09-09 03:00:36 +00:00
livelink = m . text . split ( None , 1 ) [ 1 ]
chat_id = m . chat . id
2021-09-09 20:54:36 +00:00
try :
2021-09-12 22:47:27 +00:00
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
2021-09-09 03:00:36 +00:00
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
2021-09-09 03:00:36 +00:00
msg = await m . reply ( " 🔁 **starting video streaming...** " )
2021-09-10 06:56:49 +00:00
await asyncio . sleep ( 10 )
2021-09-09 03:00:36 +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 (
2021-09-10 22:16:30 +00:00
width = 854 ,
height = 480 ,
frame_rate = 20 ,
2021-09-09 03:00:36 +00:00
) ,
) ,
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 21:26:51 +00:00
caption = f " 💡 **video streaming started!** \n \n 🏷 **Name:** { title } \n ⏱ **Duration:** ` { convert_seconds ( duration ) } m` \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 ( )
2021-09-09 03:00:36 +00:00
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...** " )
2021-09-09 03:00:36 +00:00
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 :
2021-09-09 03:00:36 +00:00
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 } ` " )
2021-09-09 03:00:36 +00:00
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 )
2021-09-09 03:00:36 +00:00
if process :
try :
process . send_signal ( SIGINT )
await asyncio . sleep ( 3 )
except Exception as e :
print ( e )
2021-09-12 22:35:49 +00:00
pass
2021-09-09 03:00:36 +00:00
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 :
2021-09-09 03:00:36 +00:00
await m . reply ( f " 🚫 **error** | ` { e } ` " )
2021-09-12 22:35:49 +00:00
2021-09-12 23:22:13 +00:00
@call_py.on_stream_end ( )
2021-09-14 03:08:25 +00:00
async def handler ( client : PyTgCalls , update : Update , m : Message ) :
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-14 03:08:25 +00:00
await call_py . leave_group_call ( chat_id )
await m . reply ( " ✅ **successfully left vc !** " )
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 } ` " )