{{ coursePublish.title }}
共{{ coursePublish.lessonNum }}课时
所属分类: {{ coursePublish.subjectLevelOne }} ( {{ coursePublish.subjectLevelTwo }} )
课程讲师: {{ coursePublish.teacherName }}
课程最终发布
确认页面
发布
课程列表
阿里云的视频点播服务
添加小节上传视频
course.js
//课程确认信息显示
getPublishCourseInfoId(courseId){
return request({
url: 'http://localhost:8001/eduservice/course/getPublishCourseInfo/'+courseId,
method: 'get'
})
} ,
publish.vue
发布新课程
{{ coursePublish.title }}
共{{ coursePublish.lessonNum }}课时
所属分类: {{ coursePublish.subjectLevelOne }} ( {{ coursePublish.subjectLevelTwo }} )
课程讲师: {{ coursePublish.teacherName }}
¥{{ coursePublish.price }}
返回上一步
发布课程
效果:

修改课程状态
EduCourseController
//修改课程状态
@PostMapping("publishCourse/{id}")
public R pubishCourse(@PathVariable String id){
EduCourse eduCourse=new EduCourse();
eduCourse.setId(id);1
eduCourse.setStatus("Normal");
courseService.updateById(eduCourse);
return R.ok();
}
前端api
course.js
最后一次的变成normal

课程列表
courseController
@GetMapping
public R getCourseList() {
List<EduCourse> list = courseService.list(null);
return R.ok().data("list", list);
}
添加api
course.js
//课程最终发布
getListCourse(){
return request({
url: 'http://localhost:8001/eduservice/course',
method: 'get'
})
} ,
list.vue
讲师列表
查 询
清空
{{ (page - 1) * limit + scope.$index + 1 }}
{{ scope.row.level === 1 ? "高级讲师" : "首席讲师" }}
修改
删除
表查询,在一对多的情况下,将多的那方,创建字段,作为外键,指向数量少的一方表的主键
阿里开发手册禁止使用物理外键,可以使用逻辑外键
外键一般不用,但是要有逻辑上的外键(因为物理外键存在时,删除数量少的表会出现删不掉的情况(因为他是其他表的外键,产生了关联,不能保证一致性))
删除顺序,应该和添加的顺序倒着来
后端
量少建议直接写sql
写细分是为了解耦和复用
编写controller:
//删除课程
@DeleteMapping("{courseId}")
public R deleteCourse(@PathVariable String courseId){
courseService.removeCourse(courseId);
return R.ok();
}
接口:
void removeCourse(String courseId);
impl:
@Override
public void removeCourse(String courseId) {
//根据课程id删除小节
videoService.removeVideoByCourseId(courseId);
//删除章节
chapterService.removeChapterByCourseId(courseId);
//删除章节描述
courseDescriptionService.removeById(courseId);
//删除课程
int result = baseMapper.deleteById(courseId);
if(result==0){
//删除失败
throw new GuliException(20001,"删除失败");
}
}
//做套娃操作
EduVideoService
void removeVideoByCourseId(String courseId);
EduVideoServiceImpl
@Override
public void removeVideoByCourseId(String courseId) {
QueryWrapper<EduVideo> wrapper=new QueryWrapper<>();
wrapper.eq("course_id",courseId);
baseMapper.delete(wrapper);
//删除对应视频的文件
}
…嗯,神奇的注释,孤陋寡闻了

EduChapterService
void removeChapterByCourseId(String courseId) ;
EduChapterServiceImpl
@Override
public void removeChapterByCourseId(String courseId) {
QueryWrapper<EduChapter> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("course_id", courseId);
baseMapper.delete(queryWrapper);
}
略
视频点播就是,可以像b站一样给别人提供网上看视频的功能

点击流量计费开通

添加Bucket

这后面会有 启用按钮,点击后变成这样:

之后设置成默认
添加音视频:

转码模板
可以设置转码,编码质量,分辨率,帧率,水印,音频参数,视频加密,还有一些字幕的设置
api(应用程序接口):许多的api接口组成了sdk
sdk(软件开发工具包):是工具包(底层是api),给后端封装成api再给前端用

引入依赖
com.aliyun
aliyun-java-sdk-core
4.6.0
com.aliyun
aliyun-java-sdk-vod
2.15.2
可能会爆红,因为aliyun-java-vod-upload还没正式开源,然后需要到官网上直接下载jar包
详情见p143(前几年是p144)
使用maven的命令进行安装
1.先下jar包
下载地址:
在帮助文档的第二个

//注意版本一致
mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.15 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.15.jar
出现以下错误
The JAVA_HOME environment variable is not defined correctly, this environment variable is needed to run this program.
这是因为Java路径没写好,在系统路径写好java路径,然后就重新打开cmd就能用了
重新输入好就能动了

先搞好maven,(如果后面怎么怎么传输失败,就用一模一样的依赖试试)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>serviceartifactId>
<groupId>com.lkwgroupId>
<version>0.0.1-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>vodartifactId>
<dependencies>
<dependency>
<groupId>com.aliyungroupId>
<artifactId>aliyun-java-sdk-coreartifactId>
<version>4.5.1version>
dependency>
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>3.10.2version>
dependency>
<dependency>
<groupId>com.aliyungroupId>
<artifactId>aliyun-java-sdk-vodartifactId>
<version>2.16.11version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.68version>
dependency>
<dependency>
<groupId>org.jsongroupId>
<artifactId>jsonartifactId>
<version>20170516version>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.8.2version>
dependency>
<dependency>
<groupId>com.aliyungroupId>
<artifactId>aliyun-sdk-vod-uploadartifactId>
<version>1.4.15version>
dependency>
dependencies>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
project>
获取视频的播放地址
获取视频播放凭证
编写test demo
InitObject.java
package com.lkw.vodtest;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
public class InitObject {
//填入AccessKey信息
public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
String regionId = "cn-shanghai"; // 点播服务接入地域
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
return client;
}
}
package com.lkw.vodtest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthRequest;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import java.util.List;
public class TestVod {
public static void main(String[] args) throws Exception {
getPlayAuth();
}
public static void getPlayAuth() throws Exception {
//创建初始化对象
//ACCESS_KEY_ID = "";
//ACCESS_KEY_SECRET = "";
DefaultAcsClient client = InitObject.initVodClient("自己的id", "自己的密钥");
//获取视频地址的erquest和response
GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();
//设置视频id
request.setVideoId("9860b583b8254449b850c7cf2ca981c8");//ID
//获取到一个响应
response = client.getAcsResponse(request);
//提取凭证
System.out.println(response.getPlayAuth());
}
public static void getPlayUrl() throws Exception {
//创建初始化对象
//ACCESS_KEY_ID = "";
//ACCESS_KEY_SECRET = "";
DefaultAcsClient client = InitObject.initVodClient("自己的id", "自己的密钥");
//获取视频地址的erquest和response
GetPlayInfoRequest request = new GetPlayInfoRequest();
GetPlayInfoResponse response = new GetPlayInfoResponse();
//设置视频id
request.setVideoId("9860b583b8254449b850c7cf2ca981c8");//ID
//获取到一个响应
response = client.getAcsResponse(request);
//提取地址
List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
//播放地址
for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
System.out.println(playInfo.getPlayURL() + " :" + response.getVideoBase().toString());
}
}
}
在上传sdk里找

安装sdk
获取sdk详情见上面maven手动导包

文件传输方法
/**
* 本地文件上传接口
*
* @param accessKeyId
* @param accessKeySecret
* @param title
* @param fileName
*/
private static void testUploadVideo(String accessKeyId, String accessKeySecret, String title, String fileName) {
UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName);
/* 可指定分片上传时每个分片的大小,默认为2M字节 */
request.setPartSize(2 * 1024 * 1024L);
System.out.println(fileName);
/* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
request.setTaskNum(1);
/* 是否开启断点续传, 默认断点续传功能关闭。当网络不稳定或者程序崩溃时,再次发起相同上传请求,可以继续未完成的上传任务,适用于超时3000秒仍不能上传完成的大文件。
注意:断点续传开启后,会在上传过程中将上传位置写入本地磁盘文件,影响文件上传速度,请您根据实际情况选择是否开启*/
//request.setEnableCheckpoint(false);
/* OSS慢请求日志打印超时时间,是指每个分片上传时间超过该阈值时会打印debug日志,如果想屏蔽此日志,请调整该阈值。单位:毫秒,默认为300000毫秒*/
//request.setSlowRequestsThreshold(300000L);
/* 可指定每个分片慢请求时打印日志的时间阈值,默认为300s*/
//request.setSlowRequestsThreshold(300000L);
/* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
//request.setIsShowWaterMark(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("8c4792cbc8694e7084fd5330e5****");
/* 工作流ID(可选)*/
//request.setWorkflowId("d4430d07361f0*be1339577859b0****");
/* 存储区域(可选)*/
//request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
/* 开启默认上传进度回调 */
//request.setPrintProgress(false);
/* 设置自定义上传进度回调(必须继承 VoDProgressListener)*/
/*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
//request.setProgressListener(new PutObjectProgressListener());
/* 设置您实现的生成STS信息的接口实现类*/
// request.setVoDRefreshSTSTokenListener(new RefreshSTSTokenImpl());
/* 设置应用ID*/
//request.setAppId("app-100****");
/* 点播服务接入点 */
//request.setApiRegionId("cn-shanghai");
/* ECS部署区域*/
// request.setEcsRegionId("cn-shanghai");
UploadVideoImpl uploader = new UploadVideoImpl();
UploadVideoResponse response = uploader.uploadVideo(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");
}
}
依赖:上面有
application.yml:
server:
port: 8003
spring:
application:
name: service-vod
profiles:
active: dev #环境设置: dev,test,prod
servlet:
multipart:
max-file-size: 1024MB
max-request-size: 1024MB
aliyun:
vod:
file:
keyid: #自己的密钥
keysecret: #自己的密钥
创建启动类
package com.lkw.vod;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//排除数据库未添加错误
public class VodApplication {
public static void main(String[] args) {
SpringApplication.run(VodApplication.class,args);
}
}
创建启动类:
package com.lkw.vod;
import lombok.Data;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//排除数据库未添加错误
@ComponentScan(basePackages ={"com.lkw"} )
public class VodApplication {
public static void main(String[] args) {
SpringApplication.run(VodApplication.class,args);
}
}
controller
package com.lkw.vod.controller;
import com.lkw.commonutils.R;
import com.lkw.vod.service.VodService;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@CrossOrigin
@RestController
@RequestMapping("/eduvod/video")
public class VodController {
//上传视频到阿里云
@Autowired
private VodService vodService;
@PostMapping("uploadAliyunVideo")
public R uploadAliyunVideo(@ApiParam(value = "视频", required = true)@RequestPart("file")MultipartFile file){
System.out.println(file);
String videoId=vodService.uploadAliyunVideo(file);
return R.ok().data("videoId",videoId);
}
}
Service
package com.lkw.vod.service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
public interface VodService {
String uploadAliyunVideo(MultipartFile file);
}
Impl
package com.lkw.vod.service.impl;
import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.lkw.vod.Utils.ConstantVodUtils;
import com.lkw.vod.service.VodService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@Service
@Slf4j
public class VodServiceImpl implements VodService {
@Override
public String uploadAliyunVideo(MultipartFile file) {
try {
log.info(ConstantVodUtils.ACCESS_KEY_ID + ConstantVodUtils.ACCESS_KEY_SECRET);
//创建文件读取流
String fileName = file.getOriginalFilename();
String title=fileName.split("\\.")[0];
InputStream inputStream = null;
inputStream = file.getInputStream();
UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET, title, fileName, inputStream );
/* 可指定分片上传时每个分片的大小,默认为2M字节 */
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
String videoId = null;
if (response.isSuccess()) {
videoId = response.getVideoId();
} else {
videoId = response.getVideoId();
}
return videoId;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
获取yml数据的工具
package com.lkw.vod.Utils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ConstantVodUtils implements InitializingBean {
@Value("${aliyun.vod.file.keyid}")
private String keyid;
@Value("${aliyun.vod.file.keysecret}")
private String keysecret;
public static String ACCESS_KEY_SECRET;
public static String ACCESS_KEY_ID;
@Override
public void afterPropertiesSet() throws Exception {
ACCESS_KEY_ID = keyid;
ACCESS_KEY_SECRET = keysecret;
}
}
请求体过大问题:(Request Entity Too Large)
如果配置了nginx,记得更改nginx的配置文件,更改文件传输大小,然后
nginx.exe -s stop
#停止nginx(可能会停不下来,需要手动查询进程关闭)
再启动
nginx.exe
#再启动

element-ui代码:
上传视频
最大支持1G,
支持3GP、ASF、AVI、DAT、DV、FLV、F4V、
GIF、M2T、M4V、MJ2、MJPEG、MKV、MOV、MP4、
MPE、MPG、MPEG、MTS、OGG、QT、RM、RMVB、
SWF、TS、VOB、WMV、WEBM 等视频格式上传
//视频操作
//上传成功的方法List
handleVodUploadSuccess(response,file,fileList){
console.log(response.data.videoId)
this.video.videoSourceId=response.data.videoId
},
//上传前
handleUploadExceed(){
this.$message.warning('如果要重新上传,请先删除已有视频')
},