Send large video on telegram through python使用python在TG上发送大视频

请勿使用翻墙!

分享知识至上!

本文专注分享知识,讨论交流python

请勿使用翻墙!

请勿使用翻墙!

请勿使用Telegram!

判了!获刑34年!

用TG的都是一群什么垃圾人?

频道管理人串谋煽惑等7罪成 判囚6年半

敬告:本文针对大陆外的留学生以及外国网友。大陆内的朋友们请勿使用翻墙,共同遵守国家法律法规!

This article is aimed at international students and foreign netizens outside the mainland. For those within the mainland, please do not use the wall and abide by national laws and regulations!

正文

据我所知,telegram提供了相关api,使得开发者可以用python与telegram进行交互。而本篇文章将实现通过python上传本地的大视频。因为telegram提供的api只允许上传小于50MB的视频,所以我们必须使用更为底层的MTProto API。
最早是在stackflow上找到这个问题。得知需要采用MTProto API的框架,叫做pyrogram,他提供了创建telegram client的办法。他也提供了send_video()的方法可以上传本地视频文件。我立刻写下代码并成功实现了他。

import asyncio
from pyrogram import Client

api_id = 12345
api_hash = "0123456789abcdef0123456789abcdef"

async def main():
    async with Client("my_account", api_id, api_hash) as app:
    	await app.send_video("me", "video.mp4")

asyncio.run(main())

在进行尝试后,发现通过这个方法上传的视频在telegram上的缩略图或者预览图是黑色的,并且不显示视频时长。在手机上播放时窗口是1:1的。
在stackflow上搜索,找到了相关文章。
https://stackoverflow.com/q/70779539
而最好的解答是

Your video file is too big. Telegram will handle videos < 10 MB and automatically create a thumbnail for you. For videos larger than that you’ll have to supply the information about the video yourself. Resolution (width and height), length, thumbnail, etc…
Additionally, you can omit the supports_streaming argument, as Pyrogram defaults this to True anyway.
To get information about your video you could use something like ffprobe.

得知使用pyrogram的send_video方法时,要手动添加视频信息,如分辨率、时间、缩略图或预览图。
这里我分别用opencv模块获取分辨率,用moviepy模块获取播放时间

import cv2
from moviepy.editor import VideoFileClip

vid = cv2.VideoCapture("a.mp4")
clip = VideoFileClip("a.mp4")

height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
duration = clip.duration

接下来是视频预览图,而send_video()方法的缩略图要求必须为jpeg格式并且宽度不大于320px。本文实现截取视频第二帧并等比例缩小到宽度为320px作为预览图。也是利用opencv模块。
这里参考了这个文章的办法

import cv2
vid = cv2.VideoCapture("a.mp4")
success, image = vid.read()
success, image = vid.read()
# read()方法返回两个参数,分别是bool类型的success和一个image。
# 有些视频第一帧是黑色,所以执行两次read()获取第二帧
height, width, channels = image.shape
r = 320 / width
max_size = (320, int(height * r))
thumb = cv2.resize(image , max_size, interpolation=cv2.INTER_AREA)
cv2.imwrite("D:/xxxx/thumb.jpeg", thumb)
# 这样thumb就被保存到本地。

这时候在使用send_video()方法

await app.send_video("me", "a.mp4",duration=int(duration)+1, width=int(width), height=int(height), thumb="D:/xxxx/thumb.jpeg")

完整代码

import cv2
from moviepy.editor import VideoFileClip

api_id = 12345
api_hash = "0123456789abcdef0123456789abcdef"

app = Client("my_account", api_id=int(api_id), api_hash=api_hash) 

async def uploadvideo():
	vid = cv2.VideoCapture("a.mp4")
	clip = VideoFileClip("a.mp4")
	
	height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
	width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
	duration = clip.duration
	
	success, image = vid.read()
	success, image = vid.read()
	# read()方法返回两个参数,分别是bool类型的success和一个image。
	# 有些视频第一帧是黑色,所以执行两次read()获取第二帧
	height, width, channels = image.shape
	r = 320 / width
	max_size = (320, int(height * r))
	thumb = cv2.resize(image , max_size, interpolation=cv2.INTER_AREA)
	cv2.imwrite("D:/xxxx/thumb.jpeg", thumb)
	# 这样thumb就被保存到本地。
	clip.close()
    vid.release() 
	await app.send_video("me", "a.mp4",duration=int(duration)+1, width=int(width), height=int(height), thumb="D:/xxxx/thumb.jpeg")
	
app.run(uploadvideo())

记得释放opencv和moviepy打开的视频文件,追求完美.
opencv释放方式具体请查看此文章

正文没有提到的参考链接如下:
pyrogram document

猜你喜欢

转载自blog.csdn.net/weixin_45518621/article/details/126455620
今日推荐