Python实现七牛云视频播放
这篇文章是使用Python的Web框架Django Rest Framework来提供视频相关的api接口,主要功能包括视频上传、视频转码、视频访问授权、删除视频文件、视频截图功能。
七牛云上的基本概念:
公开空间:可通过文件对象的 URL 直接访问。如果要使用七牛云存储的镜像存储功能,请设置空间的属性为公有。
私有空间:文件对象的访问则必须获得拥有者的授权才能访问。
资源:资源是七牛云存储服务中的逻辑存储单元。
AccessKey: 用于标识用户,用户将 AccessKey 放入访问请求,以便七牛云存储识别访问者的身份。
SecretKey: 是用于加密签名字符串和服务器端验证签名字符串的密钥。
如果将视频放在公开空间里,那么用户可以直接根据url下载视频,是不安全的,如果是付费视频,则必须放在私有空间里,这篇文章也是私有资源的处理。
首先需要有七牛云账号、创建空间,具体操作可参考:七牛云对象存储快速入门
接下来就是写代码。
1、七牛Python SDK安装:
pip install qiniu
或
easy_install qiniu
2、初始化:
在使用SDK 前,您需要一对有效的 AccessKey 和 SecretKey 签名授权。
可以通过如下步骤获得:
- 开通七牛开发者帐号
- 登录七牛开发者平台,查看 Access Key 和 Secret Key。
获取Access Key 和 Secret Key 后,调用如下两行代码进行初始化对接:
from qiniu import Auth
q = Auth(access_key, secret_key)
3、api编写,代码是契合本人所做的项目的,您不能够直接使用、api是大致相同的:
from qiniu import Auth, PersistentFop, urlsafe_base64_encode, BucketManager, build_batch_delete
from django.conf import settings
from rest_framework.decorators import list_route, detail_route
from tokenauth.decorators import is_login, admin_login from course.models import Chapter
from course.serializers import ChapterSerializer
from course.errors import INVALID_USER, INVALID_PARAMS, VIDEO_NOT_EXIST, OPERATION_NOT_ALLOWED, \
COURSE_ALREADY_ONLINE, COURSE_ALREADY_OFFLINE, CHAPTER_NOT_EXIST
from course.exception_handler import CustomError access_key = '你自己账号的access_key'
secret_key = '你自己账号的secret_key'
domain = '七牛云对象存储内容管理生成的外链默认域名'
bucket_name = '要上传的空间名称'
# 视频转码会用到私有队列,在七牛云资源主页多媒体处理点击立即添加
pipeline = '私有队列名称' class ChapterViewSet(ModelViewSet):
"""
章节 ViewSet
"""
queryset = Chapter.objects.all().order_by('created_time')
serializer_class = ChapterSerializer @list_route(methods=['get'])
@admin_login
def get_uptoken(self, request):
"""
获取上传token,有效期一个小时,前台拿到uptoken就可以上传视频文件
:param request:
:return:
"""
q = Auth(access_key, secret_key)
token = q.upload_token(bucket_name)
return Response({'uptoken': token}) @list_route(methods=['post'])
@admin_login
def transcode(self, request):
"""
七牛云视频转码切片m3u8,返回转码后的key。将视频流切割成可由HTTP下载的一个个小的音视频流,并生成一个M3U8播放列表,客户端只需要获取资源的M3U8播放列表即可播放音视频。
并且返回该视频的元信息url,前台可通过此url获取视频的时长等信息
:param request:
:param key:
:return:
"""
key = request.data.get('key', None)
if key is None:
raise CustomError(INVALID_PARAMS)
q = Auth(access_key, secret_key)
fops = 'avthumb/m3u8'
hls_name = 'hls' + UUIDTools.uuid1_hex() saveas_key = urlsafe_base64_encode(bucket_name + ':' + hls_name)
fops = fops + '|saveas/' + saveas_key
# 视频转码完成回调函数
notify_url = settings.QINIU_CALLBACK_URL + 'api/v1.0/course/chapters/complete_transcode/'
pfop = PersistentFop(q, bucket_name, pipeline, notify_url)
ops = []
ops.append(fops)
ret, info = pfop.execute(key, ops, 1)
if ret is None:
raise CustomError(VIDEO_NOT_EXIST) # 获取视频元信息链接
base_url = 'http://%s/%s?avinfo' % (domain, key)
avinfo_url = q.private_download_url(base_url) return Response({'success': True, 'hls_name': hls_name, 'avinfo_url': avinfo_url}) @list_route(methods=['post'])
def complete_transcode(self, request):
"""
七牛云视频转码完成回调
"""
origin_key = request.data.get('inputKey', None)
code = request.data.get('code', -1)
if code == 0:
TranscodeRecode.objects.create(created_by=0, updated_by=0, key=origin_key)
chapter = Chapter.objects.filter(origin_key=origin_key).values().first()
if chapter is not None:
Chapter.objects.filter(pk=chapter.get('id')).update(is_transcoded=True) return Response({'success': True}) @list_route(methods=['get'])
def ts_private_url(self, request):
"""
视频播放授权,将m3u8文件中的ts资源的url批量改写成私有url,以临时获取访问权限,有效期一个小时。
:param request:
:param key: m3u8文件的key
:return:
"""
key = request.GET.get('key', None)
if not key:
raise CustomError(INVALID_PARAMS)
q = Auth(access_key, secret_key)
base_url = 'https://%s/%s?pm3u8/0/expires/315360000' % (domain, key)
private_url = q.private_download_url(base_url, expires=3600)
return Response({'private_url': private_url}) @list_route(methods=['post'])
@admin_login
def delete_videos(self, request):
"""
删除七牛云上的视频文件
:param request:
:param keys: 逗号隔开的key
:return:
"""
keys = request.data.get('keys', None)
if not keys:
raise CustomError(INVALID_PARAMS)
keys = keys.split(',')
q = Auth(access_key, secret_key)
bucket = BucketManager(q)
ops = build_batch_delete(bucket_name, keys)
ret, info = bucket.batch(ops)
qiniu_response = info.text_body.replace('"', '\'') return Response({'success': True, 'qiniu_response': qiniu_response}) @list_route(methods=['post'])
@admin_login
def screenshot(self, request):
"""
七牛云视频截图
:param request:
:param key:
:param offset:
:return:
"""
key = request.data.get('key', None)
offset = int(request.data.get('offset', -1))
if key is None or offset < 0:
raise CustomError(INVALID_PARAMS) q = Auth(access_key, secret_key)
fops = 'vframe/jpg/offset/%d/w/480/h/360' % offset
jpg_name = 'jpg' + UUIDTools.uuid1_hex() saveas_key = urlsafe_base64_encode(bucket_name + ':' + jpg_name)
fops = fops + '|saveas/' + saveas_key pfop = PersistentFop(q, bucket_name, pipeline)
ops = []
ops.append(fops)
ret, info = pfop.execute(key, ops, 1)
if ret is None:
raise CustomError(VIDEO_NOT_EXIST)
base_url = 'https://%s/%s' % (domain, jpg_name)
# 可以设置token过期时间
jpg_url = q.private_download_url(base_url, expires=315360000)
print(jpg_url) return Response({'success': True, "jpg_url": jpg_url})
生成的api如下:
前端调用步骤:
- 调用get_uptoken,获取上传授权token,拿到token后使用js根据七牛云上传接口上传视频;
- 上传成功后调用transcode切片成m3u8,返回m3u8文件资源名称和视频时长等信息;
- 用户点击播放时,调用ts_private_url获取访问权限(参数是步骤2返回的m3u8资源名称);
- 若需要视频截图(如封面图),可以调用screenshot接口;若需要删除存储在七牛云上的视频,可以调用delete_videos接口。
4、上线之后可以使用七牛云的融合 CDN,加速视频的加载。
相关参考:
Python实现七牛云视频播放的更多相关文章
- Python在七牛云平台的应用(三)简单的人脸识别
前言 这是最后一篇介绍python在七牛云平台的应用了,因为-前两篇文章第一篇分享了怎么安装七牛的官方库以及怎么对自己的空间进行下载上传,删除等行动.而第二篇则分享了怎么利用七牛的API接口,由于七牛 ...
- Python在七牛云平台的应用(二)图片瘦身
(一)七牛云平台的图片瘦身功能简介:(引用自官网) 针对jpeg.png格式图片 瘦身后分辨率不变,格式不变. 肉眼画质不变. 图片体积大幅减少,节省 CDN 流量 官网给的图片压缩率很高,官网给的「 ...
- python+ueditor+七牛云存储整合
开发环境:python pyramid. 參考网址:http://developer.qiniu.com/docs/v6/sdk/python-sdk.html,http://my.oschina.n ...
- Python在七牛云平台的应用(一)
七牛云:(引用百度的介绍)七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化PaaS服务.围绕富媒体场景,七牛先后推出了对象存储,融合CDN加速,数据通用处理,内容反垃圾服务,以及直 ...
- 七牛云存储Python SDK使用教程 - 上传策略详解
文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k ...
- 使用七牛云存储----大家自己的图床[python]
##写博客什么的总得贴图吧,图床选来选去还是七牛吧.嗯,就是你了 [OSchaina 源码] 结合FastStone Capture 简直爽歪歪. FastStone Capture 自动保存图片到文 ...
- [python] 溜了,溜了,七牛云图片资源批量下载 && 自建图床服务器
故事背景: 七牛云最近一波测试域名操作真是把我坑死了!这简直和百度赠送你2T网盘,之后再限速一样骚操作.于是,痛定思痛自己买个云主机.自己搭图床应用! 1.七牛图片批量下载到本地 1.1 曲折尝试 当 ...
- python 读取mysql存储的文件路径下载文件,内容解析,上传七牛云,内容入es
#!/usr/bin/env python # -*- coding: utf-8 -*- import ConfigParser import json import os import re fr ...
- 七牛云的 python sdk 是如何 批量删除资源的
今天做项目的时候用到七牛云,关于对资源的操作是在后端做的,用的SDK,但是,在网上没找到详细的解析,官方文档也没有太详细的解说,所以无奈只好看下源码 这里做一下简单的记录 from qiniu imp ...
随机推荐
- A Corrupt Mayor's Performance Art
Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless pain ...
- 《DSP using MATLAB》示例Example7.2
- CF 1093E Intersection of Permutations——CDQ分治
题目:http://codeforces.com/contest/1093/problem/E 只能想到转化成查询一个区间里值在一个范围里的数的个数…… 没有想到这样适合用主席树套树状数组维护.不过据 ...
- 军哥 LNMP 常见问题
安装memcached出错: Install memcached...Notice: memcached-1.4.25.tar.gz not found!!!download now...--2016 ...
- Renesas CAT CONFIG
CAT CELL "sf_cellular_api.h" typedef enum e_sf_cellular_at_cmd_index { SF_CELLULAR_AT_CMD_ ...
- C++11标准库中cstdio头文件新增的5个格式化I/O函数学习
刚开始学网络编程,稍微扩展书上的简单C/S程序时,发现以前太忽略标准I/O这一块,查官网发现C++11新增了几个格式化I/O函数. snprintf 将格式化输出写入到有大小限制的缓存中 vfs ...
- Linnx 服务器中mysql 无法正常访问问题
本机连接远程Linnx服务器不通 1. 检测防火墙 -- 保证防火墙关闭 查看到iptables服务的当前状态:service iptables status. 但是即使服务运行了,防火墙也不一定起作 ...
- dom4j使用的小例子
product.xml: <?xml version="1.0" encoding="UTF-8"?> <root> <produ ...
- print 和 println的区别
println 输出字符后,下一个输出的字符会换行展示 print 输出字符后,下一个输出字符不会会换展示
- appium 滑动封装
#获得机器屏幕大小x,y def getSize(): x = dr.get_window_size()['width'] y = dr.get_window_size()['heig ...