腾讯云点播VOD主要用于视频资源的上传和在线播放,腾讯云官方文档也有许多相关操作的介绍,但是关于Python的文档相对较少,这里我想分享一下在Python方面自己对腾讯云VOD的研究(记得看注释)。
必备知识基础:
JavaScript,Python,Django
1、上传视频到腾讯云
1.1开通腾讯云点播VOD
地址:https://console.cloud.tencent.com/vod/overview
1.2引入js
官方文档地址:https://cloud.tencent.com/document/product/266/9239
前端引入axios.js(用于向后台发送请求,如果使用ajax请求则忽略),引入vod-js-sdk-v6(用于上传视频至腾讯云)
<script src="//cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<script src="//unpkg.com/vod-js-sdk-v6"></script>
1.3生成签名并上传视频
官方文档地址:https://cloud.tencent.com/document/product/266/9219(刚刚看了一下,今天才有Python生成签名的教程,白忙了)
前端js
const tcVod = new TcVod.default({
//生成签名才能上传视频
getSignature: getSignature // 前文中所述的获取上传签名的函数,这里必须是函数体,不能调用函数,即getSignature()
});
const uploader = tcVod.upload({
mediaFile: video_file, // 媒体文件(视频或音频或图片),类型为 File
});
// 视频上传完成时
uploader.on('media_upload', function(info) {
// uploaderInfo.isVideoUploadSuccess = true;
console.log(info);
});
// 视频上传进度
uploader.on('media_progress', function(info) {
// uploaderInfo.progress = info.percent;
});
// 封面上传完成时
uploader.on('cover_upload', function(info) {
// uploaderInfo.isCoverUploadSuccess = true;
console.log(info);
});
// 封面上传进度
uploader.on('cover_progress', function(info) {
// uploaderInfo.coverProgress = info.percent;
console.log(info)
});
//视频上传结束,返回视频详情
uploader.done().then(function (doneResult) {
// deal with doneResult
console.log(doneResult);
}).catch(function (err) {
// deal with error
console.log(err);
})
// 生成签名
function getSignature() {
return axios.post('/CreateSignature这里是你后台生成签名的url/',JSON.stringify({
"Action": "GetUgcUploadSign",
})).then(function (response) {
// console.log(response);response是后台返回的数据
return response.data.data.signature;//后台返回的签名
})
}
后端
官方文档:https://cloud.tencent.com/document/product/266/9221
views.py python生成签名(官方刚刚已经更新了Python签名的文档,建议使用官方文档,当然,这个方法是可行的)
#生成签名
class CreateSignatureView(View):
def post(self,request):
try:
#currentTimeStamp:当前时间戳,expireTime:签名有效期时间戳,random:无符号32位随机数,procedure:任务流模板名(记得先开启你的任务流,在VOD首页可以找到)
Original = 'secretId={}¤tTimeStamp={}&expireTime={}&random={}&procedure={}'.format(mykey.secretId, int(time.time()),
int(time.time()) + 10000,
random.randint(1000, 9999999),'xxx')
#通过hmac加密和base64编码生成签名,需要填你的secretKey
SignatureTmp = str(base64.b64encode(
hmac.new(mykey.secretKey.encode('utf-8'), Original.encode('utf-8'), sha1).digest() + Original.encode(
'utf-8')), 'utf-8')
except Exception as e:
logger.error(e)
return to_json_data(errno=Code.UNKOWNERR,errmsg=error_map[Code.UNKOWNERR])
return to_json_data(errno=Code.OK,data={"signature":SignatureTmp})
#to_json_data是自己用JsonResponse封装的类,这里直接使用JsonResponse即可,返回前端signature
生成后的签名可以在 https://video.qcloud.com/signature/ugcdecode.html?_ga=1.186305964.442939846.1570722999 校验
上面生成签名的算法通过对比签名生成工具(https://video.qcloud.com/signature/ugcgenerate.html?_ga=1.147964338.442939846.1570722999)生成的字符和自己用base64生成的字符即可知
urls.py
如果你开启csrf,请使用csrf_exempt取消单个类的csrf,让前端POST请求通过,或者在前端带上csrf(不做介绍,请参考:http://www.liujiangblog.com/course/django/179)
from django.views.decorators.csrf import csrf_exempt
path('CreateSignature/',csrf_exempt(views.CreateSignatureView.as_view()),name='CreateSignature'),
到这里就已经完成了视频上传,剩下的前端获取视频等基础操作不做介绍
2、获取上传后视频的详情
视频刚上传时,只能获取到视频原始的地址,但是我们需要更多的参数,比如:图片封面(如果你没有上传封面),图片gif,时长等等,这就需要我们通过获取视频的回调来得到这些数据
2.1开启回调
地址:https://console.cloud.tencent.com/vod/callback
在腾讯云点播VOD首页的回调设置开通回调,这里我使用可靠回调,勾上需要的回调,比如我需要截图,就勾上 视频按时间点截图完成回调
2.2设置任务流
地址:https://cloud.tencent.com/document/product/266/33819
2.3获取Python生成taskid和查询任务详情的代码
TaskId生成地址:https://console.cloud.tencent.com/api/explorer?Product=vod&Version=2018-07-17&Action=ProcessMedia&SignVersion= (选填参数参考:https://cloud.tencent.com/document/api/266/31773#AnimatedGraphicTaskInput)
任务(视频)详情生成地址:https://console.cloud.tencent.com/api/explorer?Product=vod&Version=2018-07-17&Action=DescribeTaskDetail&SignVersion= (TaskId填生成地址生成的TaskId)(参数和返回数据参考:https://cloud.tencent.com/document/product/266/33431)
2.4获取任务详情(视频处理后的数据)
前端js
let $video_id;
//获取文件id
uploader.done().then(function (doneResult) {
// deal with doneResult
console.log(doneResult);
// $video_url.val(doneResult.video.url);
$video_id = doneResult.fileId;//获取文件id
// console.log($video_id)
getVideoResponse({'video_title':video_title});
}).catch(function (err) {
// deal with error
console.log(err);
})
//获取回调
function getVideoResponse() {
console.log($video_id);
console.log(extra_data['video_title']);
return axios.post('/GetVideoResponse这里是后台处理回调的url/',JSON.stringify({
"fileId": $video_id,//必传参数,fileId为视频上传后返回的文件id
})).then(function (response) {
console.log(response);
//获取图片和gif,数据来自后台
$return_image_url = response.data.data.result.ProcedureTask.MediaProcessResultSet[1].CoverBySnapshotTask.Output.CoverUrl;
$return_image_gif_url = response.data.data.result.ProcedureTask.MediaProcessResultSet[0].AnimatedGraphicTask.Output.Url;
// console.log($return_image_url);
//获取时长,数据来自后台
let duration = response.data.data.result.ProcedureTask.MetaData.Duration;
return response.data.data.result;
})
}
后端
views.py
#视频回调
class GetVideoResponseView(View):
def post(self,request):
#获取前端传的数据
json_data = request.body
if not json_data:
return to_json_data(errno=Code.UNKOWNERR,errmsg=error_map[Code.UNKOWNERR])
#自己用JsonResponse写的to_json_data,无需关心,直接使用JsonResponse返回即可
try:
#转为字典
dict_data = json.loads(json_data.decode('utf-8'))
except Exception as e:
logger.error(e)
return to_json_data(errno=Code.UNKOWNERR,errmsg=error_map[Code.UNKOWNERR])
#获取fileId
try:
fileId = dict_data['fileId']
except Exception as e:
logger.error('fileId错误:{}'.format(e))
return to_json_data(errno=Code.UNKOWNERR,errmsg=error_map[Code.UNKOWNERR])
try:
task_id = getVideoTaskId(fileId) #生成TaskId
result = json.loads(getVideoResponse(task_id)) #回调视频详情数据
except Exception as e:
logger.error(e)
return to_json_data(errno=Code.UNKOWNERR,errmsg=error_map[Code.UNKOWNERR])
return to_json_data(errno=Code.OK,data={'result':result})
getVideoTaskId生成TaskId
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.vod.v20180717 import vod_client, models
from utils.tenxunyun import mykey
#生成TaskId
def getVideoTaskId(FileId):
try:
cred = credential.Credential(mykey.secretId, mykey.secretKey)
httpProfile = HttpProfile()
httpProfile.endpoint = "vod.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = vod_client.VodClient(cred, "", clientProfile)
req = models.ProcessMediaRequest()
params = '{"FileId":"%s","MediaProcessTask":{"AnimatedGraphicTaskSet":[{"Definition":20000,"StartTimeOffset":0,"EndTimeOffset":0}],"CoverBySnapshotTaskSet":[{"Definition":10,"PositionType":"Time","PositionValue":0}]}}'%FileId
req.from_json_string(params)
resp = client.ProcessMedia(req)
print(resp.to_json_string())
# print(resp.TaskId)
# print(type(resp.TaskId))
return resp.TaskId
except TencentCloudSDKException as err:
print(err)
return None
if __name__ == '__main__':
FileId = '52**8907****9726**7'#视频上传后返回的id
getVideoTaskId(FileId)
getVideoResponse回调数据
import time
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.vod.v20180717 import vod_client, models
from utils.tenxunyun import mykey
import json
def getVideoResponse(TaskId):
try:
cred = credential.Credential(mykey.secretId, mykey.secretKey)#你的secretId、secretKey
httpProfile = HttpProfile()
httpProfile.endpoint = "vod.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = vod_client.VodClient(cred, "", clientProfile)
req = models.DescribeTaskDetailRequest()
params = '{"TaskId":"%s"}'%TaskId
req.from_json_string(params)
resp = client.DescribeTaskDetail(req)
# print(resp.to_json_string())
# print(resp.Status)
#为了避免腾讯云未处理完而获取数据不全的情况,需要多次请求以获取全部数据,这里不使用递归,占内存而且多次返回,难以获取最底层的值
while resp.Status != "FINISH":
req.from_json_string(params)
resp = client.DescribeTaskDetail(req)
return resp.to_json_string()
except TencentCloudSDKException as err:
print(err)
return None
if __name__ == '__main__':
from utils.tenxunyun.getTaskId import getVideoTaskId
FileId = '52**8907****9726**7'
task_id = getVideoTaskId(FileId)
print(task_id)
result = getVideoResponse(task_id)
print('*'*100)
print(result)
urls.py
和上面相同,需要取消单个类的csrf
path('GetVideoResponse/',csrf_exempt(views.GetVideoResponseView.as_view()),name='GetVideoResponse'),
到这里,就可以拿到视频回调的详情数据了
如果上面的步骤有不懂的地方,可加Q群聊,812653899