关键词:
一、上传视频
1:使用百度云:
- 登录百度云:https://cloud.baidu.com/ 进入管理控制台;
- 开通 “视频点播VOD” 服务;
- 在后台管理系统 --> 右上角“安全认证” --> 获取 “AccessKey”;
- 在 “视频点播VOD” 界面 --> 全局设置 --> 发布设置 --> 安全设置 --> 获取 “UserKey”;
2:自定义转码设置:
1、视频需经过加密在进行发布,先创建一个编码模板(配置如下):
- 容器:选择 HLS(Http Live Streaming);
- 编码规格:high高;
- 分辨率 (视频码率):1920_1080 (2500) ,2180_720 (1024) ,800*600 (512)等;
- 加密策略:Token;
2、进入 媒资管理 进行视频上传,选择 自定义转码模板组:
二:视频的播放
1、后端代码
- 获取 ‘tokon’ 的值(参照官方文档:https://cloud.baidu.com/doc/VOD/BestPractise.html#token.E8.AE.A1.E7.AE.97.E8.A7.84.E5.88.99)
1 # 获取tokon; 2 def course_token(request): 3 # video:是视频文件的完整链接 4 file = request.GET.get(‘video‘) 5 # 过期时间; 6 expiration_time = int(time.time()) + 2 * 60 * 60 7 8 USER_ID = settings.BAIDU_CLOUD_USER_ID 9 USER_KEY = settings.BAIDU_CLOUD_USER_KEY 10 11 # file=http://hemvpc6ui1kef2g0dd2.exp.bcevod.com/mda-igjsr8g7z7zqwnav/mda-igjsr8g7z7zqwnav.m3u8 12 # 先获取扩展名;再通过‘/’分割取最后一个值,并将扩展名替换为空字符串;得到‘ID’; 13 extension = os.path.splitext(file)[1] 14 media_id = file.split(‘/‘)[-1].replace(extension, ‘‘) 15 16 # 将‘USER_KEY’进行编码;后面的‘hmac.new()’只能接受bytes类型; 17 # unicode->bytes=unicode.encode(‘utf-8‘)bytes 18 key = USER_KEY.encode(‘utf-8‘) 19 message = ‘/0/1‘.format(media_id, expiration_time).encode(‘utf-8‘) 20 21 # signature:生成签名; 22 # disgestmod:指定加密方式; 23 signature = hmac.new(key, message, digestmod=hashlib.sha256).hexdigest() 24 token = ‘0_1_2‘.format(signature, USER_ID, expiration_time) 25 return restful.result(data=‘token‘: token)
(url 映射地址:cms/course_token)
2、前端代码
- 下载 videojs 文件:http://sdk.bce.baidu.com/media-sdk/Baidu-T5Player-SDK-Web-v3.4.0.zip;
- 将 videojs 文件的 js 文件添加到项目文件目录中,以便 HTML模板 引用;
1 <!-- HTML中需引用的文件 --> 2 <script src="% static ‘videojs/video.min.js‘ %"></script> 3 <script src="% static ‘videojs/videojs-contrib-hls.min.js‘ %"></script> 4 <script src="% static ‘videojs/videojs-contrib-quality-levels.min.js‘ %"></script> 5 6 <!-- 加载播放器 --> 7 <script type="text/javascript" src="https://cdn.bdstatic.com/jwplayer/latest/cyberplayer.js"></script> 8 9 <!-- 初始化播放器的 js 文件 --> 10 <script src="% static ‘js/cms/course_detail.min.js‘ %"></script>
- 并创建一个用来加载视频的容器;
1 <div class="video-group"> 2 <span id="video-info" hidden data-video-url=" course.video_url " 3 data-cover-url=" course.cover_url "></span> 4 <!-- 用来存储播放器 --> 5 <div id="playercontainer"></div> 6 </div>
- 通过 js 初始化播放器,并传递视频地址;
1 function CourseDetail() 2 3 4 5 // 视频播放; 6 CourseDetail.prototype.initPlayer = function () 7 var videoInfoSpan = $(‘#video-info‘); 8 var video_url = videoInfoSpan.attr(‘data-video-url‘); 9 var cover_url = videoInfoSpan.attr(‘data-cover-url‘); 10 var player = cyberplayer("playercontainer").setup( 11 width: ‘100%‘, 12 height: ‘100%‘, 13 file: video_url, // 视频链接; 14 image: cover_url, // 封面图链接; 15 autostart: false, // 是否自动播放; 16 stretching: ‘uniform‘, // 扩大; 17 repeat: false, // 是否重复; 18 volume: 100, // 音量; 19 controls: true, // 底部控制栏; 20 primary: "flash", // 使用flash; 21 tokenEncrypt: true, // 采用token加密; 22 ak: ‘86dc62e1dbd4455080ab1cfc5e587b17‘, // AccessKey; 23 ); 24 25 // 视频播放前的事件; 26 player.on(‘beforePlay‘, function (e) 27 if (!/m3u8/.test(e.file)) 28 return; 29 30 xfzajax.get( 31 ‘url‘: ‘/course/course_token/‘, 32 ‘data‘: 33 ‘video‘: video_url 34 , 35 ‘success‘: function (result) 36 if (result[‘code‘] === 200) 37 var token = result[‘data‘][‘token‘]; 38 // 将‘tokon’设置入‘player’中,使播放器获取视频密码; 39 player.setToken(e.file, token); 40 else 41 alert(‘token错误!‘) 42 43 , 44 ‘fail‘: function (error) 45 console.log(error) 46 47 ) 48 ) 49 ; 50 51 CourseDetail.prototype.run = function () 52 this.initPlayer(); 53 ; 54 55 $(function () 56 var course = new CourseDetail(); 57 course.run() 58 );
三、购买视频及播放;
1、使用 PaysApi
- 文档的使用及说明:https://www.paysapi.com/docindex;
- 发起付款接口的说明文档:https://www.paysapi.com/docpay;
2、代码
- Models及HTML模板
1 # 支付页面模板; 2 class CourseOrder(models.Model): 3 uid = ShortUUIDField(primary_key=True) 4 course = models.ForeignKey("Course",on_delete=models.DO_NOTHING) 5 buyer = models.ForeignKey("xfzauth.User",on_delete=models.DO_NOTHING) 6 amount = models.FloatField(default=0) 7 pub_time = models.DateTimeField(auto_now_add=True) 8 # 支付渠道:1:代表支付宝支付;2:代表微信支付; 9 istype = models.SmallIntegerField(default=1) 10 # 支付状态:1:代表未支付;2:代表支付成功; 11 status = models.SmallIntegerField(default=1)
1 <!-- 部分相关HTML模板 --> 2 <form action="https://pay.bbbapi.com/" method="post" id="pay-form"> 3 <input type="hidden" name="uid" value="49dc532695baa99e16e01bc0"> 4 <input type="hidden" name="price" value=" course.price "> 5 <input type="hidden" name="notify_url" value=" notify_url "> 6 <input type="hidden" name="return_url" value=" return_url "> 7 <input type="hidden" name="orderid" value=" order.pk "> 8 <input type="hidden" name="orderuid" value=" request.user.pk "> 9 <input type="hidden" name="goodsname" value=" course.title "> 10 <input type="hidden" name="key" value=""> 11 <!-- 微信与支付宝支付 --> 12 <div class="pay-way"> 13 <label for="istype-wx" class="label"> 14 <input id="istype-wx" type="radio" name="istype" value="2"> 15 <span class="wx-btn fk-btn"> 16 <img src="http://nos.netease.com/test-edu-image/1BD9F69D6760CE1508D2269864AA54F8.png" alt=""> 17 </span> 18 </label> 19 <label for="istype-zfb" class="label"> 20 <input id="istype-zfb" type="radio" name="istype" value="1" checked> 21 <span class="zfb-btn fk-btn"></span> 22 </label> 23 <div style="clear: both;"></div> 24 </div> 25 <div class="submit-group"> 26 <input type="submit" value="去支付" id="submit-btn" class="submit-btn"> 27 </div> 28 </form>
- 获取“key”值
1 from utils import restful 2 from apps.xfzauth.decorators import xfz_login_required 3 from hashlib import md5 4 5 # 获取“key”;用户登录的情况下; 6 @xfz_login_required 7 def course_order_key(request): 8 goodsname = request.POST.get("goodsname") # 商品名称; 9 istype = request.POST.get("istype") # 支付渠道; 10 notify_url = request.POST.get("notify_url") # 通知回调网址; 11 orderid = request.POST.get("orderid") # 商户自定义订单号; 12 orderuid = str(request.user.pk) # 商户自定义客户号; 13 price = request.POST.get("price") # 价格; 14 return_url = request.POST.get("return_url") # 跳转网址; 15 16 # 在官网个人账户设置中的“API接口信息”中获取“token”与“uid”的值: 17 token = ‘e6110f92abcb11040ba153967847b7a6‘ 18 uid = ‘49dc532695baa99e16e01bc0‘ 19 20 # 秘钥“key”的拼接顺序:goodsname + istype + notify_url + orderid + orderuid + price + return_url + token + uid 21 key = md5((goodsname + istype + notify_url + orderid + orderuid + price + return_url + token + uid).encode( 22 "utf-8")).hexdigest() 23 return restful.result(data="key": key)
- 购买课程
1 # 购买课程; 2 @xfz_login_required 3 def course_order(request, course_id): 4 course = Course.objects.get(pk=course_id) 5 order = CourseOrder.objects.create(course=course, buyer=request.user, status=1, amount=course.price) 6 context = 7 ‘course‘: course, 8 ‘order‘: order, 9 # 跳转链接:/course/notify_url/; 10 ‘notify_url‘: request.build_absolute_uri(reverse(‘course:notify_view‘)), 11 ‘return_url‘: request.build_absolute_uri(reverse(‘course:course_detail‘, kwargs="course_id": course.pk)) 12 13 return render(request, ‘course/course_order.html‘, context=context) 14 15 # 使用订单ID更新支付状态;(关闭CSRF保护) 16 @csrf_exempt 17 def notify_view(request): 18 orderid = request.POST.get(‘orderid‘) 19 CourseOrder.objects.filter(pk=orderid).update(status=2) 20 return restful.ok()
- 前端“js”文件
1 function CourseOrder() 2 3 4 5 CourseOrder.prototype.run = function () 6 this.OrderEvent(); 7 ; 8 9 // 订购事件;(发起付款接口时需处理的数据) 10 CourseOrder.prototype.OrderEvent = (function () 11 var submitBtn = $("#submit-btn"); 12 submitBtn.click(function (event) 13 event.preventDefault(); 14 var goodsname = $("input[name=‘goodsname‘]").val(); 15 var istype = $("input[name=‘istype‘]:checked").val(); 16 var notify_url = $("input[name=‘notify_url‘]").val(); 17 var orderid = $("input[name=‘orderid‘]").val(); 18 var price = $("input[name=‘price‘]").val(); 19 var return_url = $("input[name=‘return_url‘]").val(); 20 xfzajax.post( 21 ‘url‘: ‘/course/course_order_key/‘, 22 ‘data‘: 23 ‘goodsname‘: goodsname, 24 ‘istype‘: istype, 25 ‘notify_url‘: notify_url, 26 ‘orderid‘: orderid, 27 ‘price‘: price, 28 ‘return_url‘: return_url 29 , 30 ‘success‘: function (result) 31 if(result[‘code‘] === 200) 32 var key = result[‘data‘][‘key‘]; 33 var keyInput = $("input[name=‘key‘]"); 34 keyInput.val(key); 35 $("#pay-form").submit(); 36 37 38 ); 39 ); 40 ); 41 42 $(function () 43 var order = new CourseOrder(); 44 order.run(); 45 );
视频分布式上传方案详解(代码片段)
...了。这时候被借到学院这边来做一些优化改造,其中视频分布式上传这个功能存在很多问题,急需改造处理学院视频上传功能简介学院这边上传视频的大致步骤如下老师在教师管理后台上传视频教师管理后台再把视频上... 查看详情
通过网页上传阿里云点播视频(代码片段)
由于工作关系,需要不定时在阿里云上传视频文件,为了更加简化操作提升效率,结合WPF及阿里云SDK写了一个视频预览、截图、视频翻转以及本地视频上传并获取上传后视频的ImgUrl和videoUrl等关键播放参数的小工具由于SDK中没有... 查看详情
react学习笔记(番外一)——video.js视频播放组件的入门及排坑经历(代码片段)
React学习笔记(番外一)——video.js视频播放组件的入门及排坑经历前言video.js的支持的视频格式及编码方式支持的扩展名(格式)支持的视频编码video.js的安装将video.js引入React自定义播放器控件引用自定义视频播... 查看详情
学成在线(第14天)(代码片段)
视频处理 需求分析原始视频通常需要经过编码处理,生成m3u8和ts文件方可基于HLS协议播放视频。通常用户上传原始视频,系统自动处理成标准格式,系统对用户上传的视频自动编码、转换,最终生成m3u8文件和ts文件,处... 查看详情
音视频开发之旅(64)-部分android手机编码的视频在ios上无法播放(代码片段)
...析问题原因问题解决资料收获一、问题描述用小米11录制视频上传后,在iPhone的Safari浏览器或者应用的H5中无法播放,而android设备上的确实可以正常播放。同样的操作,在一些其他android的手机上传的视频,在ios端... 查看详情
谈一谈:音视频同步原理及实现(代码片段)
本文主要描述音视频同步原理,及常见的音视频同步方案,并以代码示例,展示如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放。内容如下:1.音视频同步简单介绍2.DTS和PTS简介2.1.... 查看详情
m3u8视频加密及播放(代码片段)
前提准备:1、一个mp4文件play.mp42、安装ffmpeg和openssl环境配置:一、配置ffmpeg下载好并安装ffmpeg到本地;配置环境变量ffmpeg目录的bin;检验成功:打开cmd输入ffmpeg,只要不是弹出"不是内部或外部命令,也不是可运行的程序或批处理文件... 查看详情
pc端和移动端都支持视频video自动播放的代码(代码片段)
需求说明今天有个朋友微信上说目前他们在做抖音短视频的内容创作,方向是国家级非物质文化遗产「汝瓷」,想在他们官方网站上增加短视频的功能,将抖音的内容页上传到网站上。其实这个功能并不复杂,只... 查看详情
pc端和移动端都支持视频video自动播放的代码(代码片段)
需求说明今天有个朋友微信上说目前他们在做抖音短视频的内容创作,方向是国家级非物质文化遗产「汝瓷」,想在他们官方网站上增加短视频的功能,将抖音的内容页上传到网站上。其实这个功能并不复杂,只... 查看详情
webrtc音视频采集和播放示例及mediastream媒体流解析(代码片段)
WebRTC音视频采集和播放示例及MediaStream媒体流解析目录示例代码——同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音API解析mediaDevicesMediaStream媒体流1.示例代码——同时打开摄像头和麦克风,并在页面显示... 查看详情
pc端和移动端都支持视频video自动播放的代码(代码片段)
需求说明今天有个朋友微信上说目前他们在做抖音短视频的内容创作,方向是国家级非物质文化遗产「汝瓷」,想在他们官方网站上增加短视频的功能,将抖音的内容页上传到网站上。其实这个功能并不复杂,只... 查看详情
pc端和移动端都支持视频video自动播放的代码(代码片段)
需求说明今天有个朋友微信上说目前他们在做抖音短视频的内容创作,方向是国家级非物质文化遗产「汝瓷」,想在他们官方网站上增加短视频的功能,将抖音的内容页上传到网站上。其实这个功能并不复杂,只... 查看详情
通过vue+flvjs在html5中播放flv格式视频文件—demo及api(代码片段)
目前主流浏览器不能直接嵌入并且播放FLV文件,所以直接用video标签播放是行不通的。因此提供两种解析方法嵌入一个swf媒体播放文件,并利用该文件来播放你预设的文件。这里推荐dplayer——http://dplayer.js.org/zh/guide.html#fl... 查看详情
潘多拉-视频播放器,一个轻量的视频播放器(代码片段)
潘多拉-视频播放器轻量视频播放器,该项目是从https://github.com/getActivity/AndroidProject-Kotlin中抽离出的一个视频播放器,之前没有单独设置项目,我在使用过程中觉得这个挺方便好用的,所以为了方便使用,单独剥离出来,可以单独在项目... 查看详情
酷播云上传视频后如何获取播放代码
第1步:登录酷播云管理平台后,点击【视频列表】,点选一个视频,右侧就会显示该视频的一些操作,如下图,依次分别为“设定视频参数区块”、“设定播放参数区块”、“视频代码区块”。 第2步:找到右侧的“视... 查看详情
quartz结合多线程处理后台业务(代码片段)
最近项目中有播放视频的需求,技术选型采用UMS播放器,免费版只能播放FLV格式的视频文件,因此需要对用户上传的视频进行格式转换,转换工具为FormatFactory,功能还是比较强大的。但是面临的一个问题,视频转换是非常耗... 查看详情
web无插件播放视频之rtsp(代码片段)
...为一个从未接触过实时流(直播流)的人,我之前对实时视频一直没有概念,而最近参与的项目刚好有视频监控的需求,因此我对webs无插件实时流的展示进行了学习及研究,以下案例均经过实践(不足之处望指教)。概念:视... 查看详情
android主流视频播放及缓存实现原理调研
参考技术A本文针对视频播放及缓存方案进行调研,对于Android端常用的视频播放器的缓存策略介绍及实现原理。实现简单,逻辑易懂。在播放器与视频源服务器之间加了一层代理服务器,截取视频播放器发送的请求,根据截取的... 查看详情