第五次课-阿里云视频点播技术
分类: springboot 专栏: 新版在线教育项目 标签: 阿里云视频点播
2024-04-03 12:06:45 778浏览
视频点播
视频点播(ApsaraVideo for VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速于一体的一站式音视频点播解决方案。
应用场景
- 音视频网站:无论是初创视频服务企业,还是已拥有海量视频资源,可定制化的点播服务帮助客户快速搭建拥有极致观看体验、安全可靠的视频点播应用。
- 短视频:集音视频拍摄、特效编辑、本地转码、高速上传、自动化云端转码、媒体资源管理、分发加速、播放于一体的完整短视频解决方案。目前已帮助1000+APP快速实现手机短视频功能。
- 直播转点播:将直播流同步录制为点播视频,用于回看。并支持媒资管理、媒体处理(转码及内容审核/智能首图等AI处理)、内容制作(云剪辑)、CDN分发加速等一系列操作。
- 在线教育:为在线教育客户提供简单易用、安全可靠的视频点播服务。可通过控制台/API等多种方式上传教学视频,强大的转码能力保证视频可以快速发布,覆盖全网的加速节点保证学生观看的流畅度。防盗链、视频加密等版权保护方案保护教学内容不被窃取。
- 视频生产制作:提供在线可视化剪辑平台及丰富的OpenAPI,帮助客户高效处理、制作视频内容。除基础的剪切拼接、混音、遮标、特效、合成等一系列功能外,依托云剪辑及点播一体化服务还可实现标准化、智能化剪辑生产,大大降低视频制作的槛,缩短制作时间,提升内容生产效率。
- 内容审核:应用于短视频平台、传媒行业审核等场景,帮助客户从从语音、文字、视觉等多维度精准识别视频、封面、标题或评论的违禁内容进行AI智能审核与人工审核。
功能介绍
视频转码:比如普通原画视频可以转成高清,标清等
分发加速:播放的速度更快,尽量少提示正在缓存中
主要用到:上传和管理
开通视频点播云平台
选择视频点播服务
产品->企业应用->视频云->视频点播
开通视频点播
选择使用流量计费
资费说明
https://www.aliyun.com/price/product?spm=a2c4g.11186623.2.12.7fbd59b9vmXVN6#/vod/detail
- 后付费
- 套餐包
- 欠费说明
- 计费案例:https://help.aliyun.com/document_detail/64032.html?spm=a2c4g.11186623.4.3.363db1bcfdvxB5
整体流程
使用视频点播实现音视频上传、存储、处理和播放的整体流程如下:
- 用户获取上传授权。
- VoD下发 上传地址和凭证 及 VideoId。
- 用户上传视频保存视频ID(VideoId)。
- 用户服务端获取播放凭证。
- VoD下发带时效的播放凭证。
- 用户服务端将播放凭证下发给客户端完成视频播放。
视频点播服务的基本使用
完整的参考文档
https://help.aliyun.com/product/29932.html?spm=a2c4g.11186623.6.540.3c356a58OEmVZJ
设置转码模板并加密
选择全局设置 > 转码设置,单击添加转码模板组。
在视频转码模板组页面,根据业务需求选择封装格式和清晰度。
或直接将已有的模板设置为默认即可
可以设置视频加密,这样别人拿到我的播放地址也无法播放
分类管理
选择全局设置 > 分类管理
上传视频文件
选择媒资库 > 音视频,单击上传音视频
配置域名
加密的视频最好是设置一下这个域名
在控制台查看视频
此时视频可以在阿里云控制台播放
获取web播放器代码
java上传视频到阿里云
看着官方的文档操作即可
@ApiOperation(value = "上传视频到阿里云视频点播")
@PostMapping
public ResultDto uploadVod(MultipartFile vod){
try {
String fileName = vod.getOriginalFilename();
String title = fileName.substring(0, fileName.lastIndexOf("."));
UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, vod.getInputStream());
/* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/
//request.setShowWaterMark(true);
/* 自定义消息回调设置及上传加速设置(可选), Extend为自定义扩展设置,MessageCallback为消息回调设置,AccelerateConfig为上传加速设置(上传加速功能需要先申请开通后才能使用)*/
//request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackType\":\"http\",\"CallbackURL\":\"http://example.aliyundoc.com\"},\"AccelerateConfig\":{\"Type\":\"oss\",\"Domain\":\"****Bucket.oss-accelerate.aliyuncs.com\"}}");
/* 视频分类ID(可选) */
//request.setCateId(0);
/* 视频标签,多个用逗号分隔(可选) */
//request.setTags("标签1,标签2");
/* 视频描述(可选)*/
//request.setDescription("视频描述");
/* 封面图片(可选)*/
//request.setCoverURL("http://cover.example.com/image_01.jpg");
/* 模板组ID(可选)*/
//request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56****");
/* 工作流ID(可选)*/
//request.setWorkflowId("d4430d07361f0*be1339577859b0****");
/* 存储区域(可选)*/
//request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
/* 开启默认上传进度回调 */
// request.setPrintProgress(true);
/* 设置自定义上传进度回调(必须继承 VoDProgressListener) */
/*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
// request.setProgressListener(new PutObjectProgressListener());
/* 设置应用ID*/
//request.setAppId("app-100****");
/* 点播服务接入点 */
//request.setApiRegionId("cn-shanghai");
/* ECS部署区域*/
// request.setEcsRegionId("cn-shanghai");
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
if (response.isSuccess()) {
System.out.print("VideoId=" + response.getVideoId() + "\n");
} else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
System.out.print("VideoId=" + response.getVideoId() + "\n");
System.out.print("ErrorCode=" + response.getCode() + "\n");
System.out.print("ErrorMessage=" + response.getMessage() + "\n");
throw new JfException(Integer.valueOf(response.getCode()),response.getMessage());
}
return ResultDto.success("上传成功",response.getVideoId());
} catch (IOException e) {
e.printStackTrace();
return ResultDto.error("上传失败");
}
}
设置文件上传大小的限制
spring.servlet.multipart.maxFileSize=10MB
spring.servlet.multipart.maxRequestSize=100MB
上传组件设置请求头
项目加了安全框架以后,由于上传图片的请求是由<el-upload>组件直接发送到服务端的,没有经过request.js添加请求头 ‘Authorization’,所以会被登录过滤器拦截,显示未登录,这个时候可以在 <el-upload>组件中设置请求头
java获取视频播放地址
备注:根据视频id获取到
对于不加密的视频来说,只要拿到播放地址就可以直接播放。但对于加密的视频来说,拿到播放地址也无法播放。
public class Sample {
public static com.aliyun.vod20170321.Client Initialization(String regionId) throws Exception {
Config config = new Config();
// 您的AccessKey ID
config.accessKeyId = "LTAI5tFicE3BjrB7XWCmjN2k";
// 您的AccessKey Secret
config.accessKeySecret = "B0yaYi7PdlK023lznurimrG9nUOCIf";
// 您的可用区ID
config.regionId = regionId;
return new com.aliyun.vod20170321.Client(config);
}
public static GetPlayInfoResponse GetPlayInfoSample(com.aliyun.vod20170321.Client client, String videoId) throws Exception {
GetPlayInfoRequest request = new GetPlayInfoRequest();
// 视频ID。
request.videoId = videoId;
GetPlayInfoResponse response = client.getPlayInfo(request);
return response;
}
public static void main(String[] args_) throws Exception {
// java.util.List<String> args = java.util.Arrays.asList(args_);
try {
String regionId = "cn-hangzhou";
String videoId = "80ec84f7f15271eeb6416733a68f0102";
com.aliyun.vod20170321.Client client = Sample.Initialization(regionId);
GetPlayInfoResponse responseGetPlayInfo = Sample.GetPlayInfoSample(client, videoId);
com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(com.aliyun.teautil.Common.toMap(responseGetPlayInfo)));
} catch (TeaException error) {
com.aliyun.teaconsole.Client.log(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
com.aliyun.teaconsole.Client.log(error.message);
}
}
}
需要用到的依赖
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-console</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-util</artifactId>
<version>0.2.10</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>darabonba-env</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>vod20170321</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.0.8</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>[1.0.3, 2.0.0)</version>
</dependency>
java获取播放凭证(重要)
备注:根据视频id获取到
对于加密视频的播放,只能用这个凭证的方式
public class GetVideoPlayAuth {
/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
public static com.aliyun.vod20170321.Client createClient() throws Exception {
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId("LTAI5tFicE3BjrB7XWCmjN2k")
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
.setAccessKeySecret("B0yaYi7PdlK023lznurimrG9nUOCIf");
// Endpoint 请参考 https://api.aliyun.com/product/vod
config.endpoint = "vod.cn-shanghai.aliyuncs.com";
return new com.aliyun.vod20170321.Client(config);
}
public static void main(String[] args_) throws Exception {
com.aliyun.vod20170321.Client client = GetVideoPlayAuth.createClient();
com.aliyun.vod20170321.models.GetVideoPlayAuthRequest getVideoPlayAuthRequest = new com.aliyun.vod20170321.models.GetVideoPlayAuthRequest()
.setVideoId("9093cd72f15a71eeaf4a6633b79f0102");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// 复制代码运行请自行打印 API 的返回值
com.aliyun.vod20170321.models.GetVideoPlayAuthResponse resp = client.getVideoPlayAuthWithOptions(getVideoPlayAuthRequest, runtime);
com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(resp));
} catch (TeaException error) {
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
System.out.println(error.getMessage());
// 诊断地址
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
System.out.println(error.getMessage());
// 诊断地址
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}
}
java删除视频
删除的时候可以批量删除多个
视频播放测试
可以在线配置好再写代码
https://player.alicdn.com/aliplayer/setting/setting.html?spm=a2c4g.125576.0.0.72d15398Sp2vVZ
分两种:根据地址播放和根据凭证播放
- 根据地址播放
var player = new Aliplayer({
id: 'J_prismPlayer',
source: '<your play URL>',//播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
},function(player){
console.log('The player is created.')
});
- 根据凭证播放
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<title>点播私有加密播放测试用例</title>
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.19/skins/default/aliplayer-min.css" />
<script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.9.19/aliplayer-min.js"></script>
</head>
<body>
<div class="prism-player" id="J_prismPlayer"></div>
<script>
var player = new Aliplayer({
id: 'J_prismPlayer',
width: '100%',
vid : '<your video ID>',//必选参数。可以通过点播控制台(路径:媒资库>音/视频)查询。示例:1e067a2831b641db90d570b6480f****。
playauth : '<your PlayAuth>',//必选参数。参数值可通过调用GetVideoPlayAuth接口获取。
encryptType: 1, //当播放私有加密流时需要设置本参数值为1。其它情况无需设置。
playConfig:{EncryptType:'AliyunVoDEncryption'}, //当您输出的M3U8流中,含有其他非私有加密流时,需要指定此参数。
},function(player){
console.log('The player is created.')
});
</script>
</body>
</html>
以上写法都是html里的写法,下面是vue的写法
参考文章:
https://developer.aliyun.com/article/646391
整理如下:
播放器组件vue代码
<template>
<div class="prism-player" :id="playerId" :style="playStyle"></div>
</template>
<script>
export default {
name: "Aliplayer",
props: {
//媒体转码服务的媒体Id。
vid: {
type: String,
default: ""
},
//播放权证
playauth: {
type: String,
default: ""
},
//容器的大小
height: {
type: String,
default: "460px"
},
//容器的大小
width: {
type: String,
default: "100%"
},
//视频的高度大小
videoWidth: {
type: String,
default: "100%"
},
//视频的宽度大小
videoHeight: {
type: String,
default: "100%"
},
//播放器自动加载,目前仅h5可用
preload: {
type: Boolean,
default: false
},
//播放器默认封面图片,请填写正确的图片url地址。需要autoplay为’false’时,才生效
cover: {
type: String,
default: ""
},
//播放内容是否为直播,直播时会禁止用户拖动进度条。
isLive: {
type: Boolean,
default: false
},
//播放器是否自动播放,在移动端autoplay属性会失效。
autoplay: {
type: Boolean,
default: false
},
//播放器自动循环播放。
rePlay: {
type: Boolean,
default: false
},
//指定使用H5播放器。
useH5Prism: {
type: Boolean,
default: false
},
//H5是否内置播放,有的Android浏览器不起作用。
playsinline: {
type: Boolean,
default: false
},
//默认为‘hover’。可选的值为:‘click’、‘hover’、‘always’。
controlBarVisibility: {
type: String,
default: "hover"
},
/***
*
*指定播放地址格式,只有使用vid的播放方式时支持
可选值为’mp4’、’m3u8’、’flv’、’mp3’,默认为空,仅H5支持。
* */
format: {
type: String,
default: "m3u8"
},
/***
*
* 指定返回音频还是视频,只有使用vid的播放方式时支持。
可选值为’video’和’audio’,默认为’video’
‘audio’主要是针对只包含音频的视频格式,比如音频的mp4,仅H5支持。
* */
mediaType: {
type: String,
default: "video"
},
/***
* 指定排序方式,只有使用vid + plauth播放方式时支持。
‘desc’表示按倒序排序(即:从大到小排序)
‘asc’表示按正序排序(即:从小到大排序)
默认值:‘asc’,仅H5支持。
* */
qualitySort: {
type: String,
default: "asc"
},
/**
* 加密类型,播放点播私有加密视频时,设置值为1,默认值为0。
* */
encryptType: {
type: Number,
default: 1
},
playStyle: {
type: String,
default: ""
},
aliplayerSdkPath: {
// Aliplayer 代码的路径
type: String,
default: "https://g.alicdn.com/de/prismplayer/2.9.3/aliplayer-min.js"
},
},
data() {
return {
playerId: "aliplayer_" + Math.random().toString(36).substr(2),
scriptTagStatus: 0,
isReload: false,
instance: null
};
},
created() {
if (window.Aliplayer !== undefined) {
// 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
this.scriptTagStatus = 2;
this.initAliplayer();
} else {
// 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
this.insertScriptTag();
}
},
mounted() {
if (window.Aliplayer !== undefined) {
// 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
this.scriptTagStatus = 2;
this.initAliplayer();
} else {
// 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
this.insertScriptTag();
}
},
methods: {
insertScriptTag() {
const _this = this;
let playerScriptTag = document.getElementById("playerScriptTag");
// 如果这个tag不存在,则生成相关代码tag以加载代码
if (playerScriptTag === null) {
playerScriptTag = document.createElement("script");
playerScriptTag.type = "text/javascript";
playerScriptTag.src = this.aliplayerSdkPath;
playerScriptTag.id = "playerScriptTag";
let s = document.getElementsByTagName("head")[0];
s.appendChild(playerScriptTag);
}
if (playerScriptTag.loaded) {
_this.scriptTagStatus++;
} else {
playerScriptTag.addEventListener("load", () => {
_this.scriptTagStatus++;
playerScriptTag.loaded = true;
_this.initAliplayer();
});
}
_this.initAliplayer();
},
initAliplayer() {
const _this = this;
// scriptTagStatus 为 2 的时候,说明两个必需引入的 js 文件都已经被引入,且加载完成
if (
_this.scriptTagStatus === 2 &&
(_this.instance === null || _this.reloadPlayer)
) {
_this.instance && _this.instance.dispose();
// document.querySelector("#" +_this.playerId).innerHTML = "";
// Vue 异步执行 DOM 更新,这样一来代码执行到这里的时候可能 template 里面的 script 标签还没真正创建
// 所以,我们只能在 nextTick 里面初始化 Aliplayer
_this.$nextTick(() => {
_this.instance = window.Aliplayer({
id: _this.playerId,
qualitySort:_this.qualitySort,
format:_this.format,
mediaType:_this.mediaType,
vid: _this.vid,
playauth: _this.playauth,
width: _this.width,
height: _this.height,
videoWidth: _this.videoWidth,
videoHeight: _this.videoHeight,
preload: _this.preload,
playsinline:_this.playsinline,
isLive: _this.isLive,
rePlay: _this.rePlay,
autoplay: _this.autoplay,
useH5Prism: _this.useH5Prism,
controlBarVisibility: _this.controlBarVisibility,
encryptType: _this.encryptType,
});
// 绑定事件,当 AliPlayer 初始化完成后,将编辑器实例通过自定义的 ready 事件交出去
_this.instance.on("ready", () => {
this.$emit("ready", _this.instance);
});
_this.instance.on("play", () => {
this.$emit("play", _this.instance);
});
_this.instance.on("pause", () => {
this.$emit("pause", _this.instance);
});
_this.instance.on("ended", () => {
this.$emit("ended", _this.instance);
});
_this.instance.on("liveStreamStop", () => {
this.$emit("liveStreamStop", _this.instance);
});
_this.instance.on("m3u8Retry", () => {
this.$emit("m3u8Retry", _this.instance);
});
_this.instance.on("hideBar", () => {
this.$emit("hideBar", _this.instance);
});
_this.instance.on("waiting", () => {
this.$emit("waiting", _this.instance);
});
_this.instance.on("snapshoted", () => {
this.$emit("snapshoted", _this.instance);
});
_this.instance.on("timeupdate", () => {
this.$emit("timeupdate", _this.instance);
});
_this.instance.on("requestFullScreen", () => {
this.$emit("requestFullScreen", _this.instance);
});
_this.instance.on("cancelFullScreen", () => {
this.$emit("cancelFullScreen", _this.instance);
});
_this.instance.on("error", () => {
this.$emit("error", _this.instance);
});
});
}
},
/**
* 播放视频
*/
play: function () {
this.instance.play();
},
/**
* 暂停视频
*/
pause: function () {
this.instance.pause();
},
/**
* 重播视频
*/
replay: function () {
this.instance.replay();
},
/**
* 跳转到某个时刻进行播放
* @argument time 的单位为秒
*/
seek: function (time) {
this.instance.seek(time);
},
/**
* 获取当前时间 单位秒
*/
getCurrentTime: function () {
return this.instance.getCurrentTime();
},
/**
*获取视频总时长,返回的单位为秒
* @returns 返回的单位为秒
*/
getDuration: function () {
return this.instance.getDuration();
},
/**
获取当前的音量,返回值为0-1的实数ios和部分android会失效
*/
getVolume: function () {
return this.instance.getVolume();
},
/**
设置音量,vol为0-1的实数,ios和部分android会失效
*/
setVolume: function (vol) {
this.instance.setVolume(vol);
},
/**
*直接播放视频url,time为可选值(单位秒)目前只支持同种格式(mp4/flv/m3u8)之间切换暂不支持直播rtmp流切换
*@argument url 视频地址
*@argument time 跳转到多少秒
*/
loadByUrl: function (url, time) {
this.instance.loadByUrl(url, time);
},
/**
* 设置播放速度
*@argument speed 速度
*/
setSpeed: function (speed) {
this.instance.setSpeed(speed);
},
/**
* 设置播放器大小w,h可分别为400px像素或60%百分比chrome浏览器下flash播放器分别不能小于397x297
*@argument w 播放器宽度
*@argument h 播放器高度
*/
setPlayerSize: function (w, h) {
this.instance.setPlayerSize(w, h);
},
/**
*目前只支持H5播放器。
暂不支持不同格式视频间的之间切换。
暂不支持直播rtmp流切换。
*/
replayByVidAndPlayAuth: function (vid, accId, accSecret, stsToken, authInfo, domainRegion) {
this.instance.replayByVidAndPlayAuth(vid, accId, accSecret, stsToken, authInfo, domainRegion);
},
/***
* 重新设置vid和权限,目前只支持H5播放器。
暂不支持不同格式视频间的之间切换。
暂不支持直播rtmp流切换。
* @param vid 视频ID
* @param playauth 播放权限
*/
replayByVidAndAuthInfo: function (vid, playauth) {
this.instance.replayByVidAndAuthInfo(vid, playauth);
},
/**
* 目前只支持HTML5界面上的重载功能,暂不支持直播rtmp流切换m3u8)之间切换,暂不支持直播rtmp流切换
*@argument vid 视频id
*@argument playauth 播放凭证
*/
reloaduserPlayInfoAndVidRequestMts: function (vid, playauth) {
this.instance.reloaduserPlayInfoAndVidRequestMts(vid, playauth);
},
/***
*设置截图参数
* @param width 宽度
* @param height 高度
* @param rate 截图质量
*/
setSanpshotProperties: function (width, height, rate) {
this.instance.setSanpshotProperties(width, height, rate);
},
/**
* 设置封面地址
* @param cover 封面地址
*/
setCover: function (cover) {
this.instance.setCover(cover);
},
reloadPlayer: function () {
this.isReload = true;
this.initAliplayer();
this.isReload = false;
}
}
};
</script>
<style>
@import url(https://g.alicdn.com/de/prismplayer/2.9.3/skins/default/aliplayer-min.css);
</style>
在线播放视频的vue代码
<template>
<div class="app-container">
<el-button type="" @click="seeVideo('e4113840ee0e71ed804f0764a0fd0102')">查看第一个视频</el-button>
<el-button type="" @click="seeVideo('34ae63b0ee0371ed80380675b3ed0102')">查看第二个视频</el-button>
<!--阿里云播放器-->
<el-dialog
class="video"
@close="colseVideo()"
:visible.sync="playShow"
>
<ali-player
v-if="playAuth"
:vid="vid"
:playauth="playAuth"
qualitySort="asc"
format="m3u8"
mediaType="video"
:encryptType=1
ref="player"
:autoplay=false
:isLive=false
:rePlay=false
:preload=true
controlBarVisibility="hover"
:useH5Prism=true
>
</ali-player>
</el-dialog>
</div>
</template>
<script>
import { getAuth } from '@/api/vod'
import VueAliplayer from '@/components/AliPlayer'
export default {
components: { "ali-player": VueAliplayer },
data() {
return {
playShow: false,
vid: '', //视频vid
playAuth: '', //鉴权地址
};
},
methods: {
colseVideo(){
// //重新子组件初始化
this.$refs.player.initAliplayer()
},
seeVideo(vid) {
var that = this
that.vid=''
that.playAuth=''
//根据vid去查凭证
getAuth(vid).then(res => {
that.vid = vid
that.playAuth = res.data
that.playShow = true
})
},
}
}
</script>
<style >
.video .el-dialog__header {
padding: 0;
}
.video .el-dialog__body {
padding: 0;
}
</style>
遇到的问题:明明已经获取到了凭证但就是无法播放!!!
原因是:子组件里面需要用到父组件传过来的播放凭证 ,而我们父组件的凭证是发送ajax请求到后台拿到的,还没等到父组件拿到这个凭证的时候,子组件就已经加载了,导致始终播放不了。
解决思路:让子组件延迟加载。
最终的demo效果如下
删除课程
如果用户确定删除,则首先删除视频,小节,章节,描述,课程
可以考虑加个事务
前台页面
把前台的静态页面素材整理出来
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论