在学成教育中,第三方机构需要将课程视频、作业文档等信息上传,我们采用第三方存储服务来对这些资源做存储,用七牛云存储图片、阿里云做视频点播功能。
当我们把这些文件上传到第三方服务后,我们需要将第三方服务返回的信息给我们的后端,再由后端将其写入到数据库中。当我们需要访问媒资时首先访问数据库查找对应的媒资信息,再根据fileId向七牛云或阿里云发送获取媒资url的请求,返回给浏览器。
上面讲了媒资管理“增”和“查”的操作,而“删”并不是删除媒资,也不是删除数据库记录,只是把对应记录的status修改为0(对外不可见),媒资管理并不存在“改”的操作,机构只能修改媒资与章节的绑定关系,并不能对已经上传的媒资进行修改操作
媒资表(规范字段、媒资信息、公司信息、审核信息、上传者信息)
@Data
@ApiModel("视频上传凭证封装类")
public class VodUploadToken {
/**
* 请求id
*/
@ApiModelProperty("请求id")
private String requestId;
/**
* 上传视频的唯一标识
*/
@ApiModelProperty("上传视频的唯一标识")
private String videoId;
/**
* 上传URL
*/
@ApiModelProperty("上传URL")
private String uploadAddress;
/**
* 上传凭证
*/
@ApiModelProperty("上传凭证")
private String uploadAuth;
}
获取token
/**
* 向阿里云请求上传token
* @param request (需要包含title、fileName)
* @return VodUploadToken(videoId、uploadAuth(token)、uploadAddress)
*/
@RequestMapping("media/vod-token")
@Override
public VodUploadToken generatorVodToken(@RequestBody VodUploadRequest request) {
try {
//1.初始化客户端
DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKey, secretKey);
//2.构建请求并发送,得到响应
CreateUploadVideoResponse response = AliyunVODUtil.createUploadVideo(client, request.getTitle(), request.getFileName());
//3.解析响应结果
VodUploadToken uploadToken = new VodUploadToken();
uploadToken.setUploadAuth(response.getUploadAuth());
uploadToken.setVideoId(response.getVideoId());
uploadToken.setUploadAddress(response.getUploadAddress());
uploadToken.setRequestId(response.getRequestId());
return uploadToken;
}catch (Exception e){
System.out.println(e.getMessage());
ExceptionCast.cast(MediaErrorCode.E_140011);
}
return null;
}
刷新token
/**
* 刷新上传token
* @param videoId
* @return
*/
@GetMapping("media/refresh-vod-token/{videoId}")
@Override
public VodUploadToken refreshToken(@PathVariable String videoId) {
try {
//1.初始化客户端
DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKey, secretKey);
//2.发送刷新token的请求并得到响应
RefreshUploadVideoResponse response = AliyunVODUtil.refreshUploadVideo(client, videoId);
//3.解析响应结果
VodUploadToken uploadToken = new VodUploadToken();
uploadToken.setUploadAuth(response.getUploadAuth());
uploadToken.setVideoId(response.getVideoId());
uploadToken.setUploadAddress(response.getUploadAddress());
uploadToken.setRequestId(response.getRequestId());
return uploadToken;
}catch (Exception e){
ExceptionCast.cast(MediaErrorCode.E_140015);
}
return null;
}
mediaVO
@Data
@ApiModel(value="MediaVO", description="媒体资源VO对象")
public class MediaVO implements Serializable {
/**
* 文件名称
*/
@ApiModelProperty(value = "文件名称")
@NotNull(message = "文件名不能为空")
private String filename;
/**
* 文件类型(文档,音频,视频)
*/
@ApiModelProperty(value = "文件类型")
@NotNull(message = "文件类型不能为空")
private String type;
/**
* 标签
*/
@ApiModelProperty(value = "文件标签")
private String tags;
/**
* 存储源
*/
@ApiModelProperty(value = "存储源")
private String bucket;
/**
* 文件标识
*/
@ApiModelProperty(value = "文件唯一标识:七牛云的key,阿里云的videoId")
@NotNull(message = "文件标识不能为空")
private String fileId;
/**
* 媒资文件访问地址
*/
@ApiModelProperty(value = "文件地址")
private String url;
@ApiModelProperty(value = "视频长度")
private String timelength;
/**
* 备注
*/
@ApiModelProperty(value = "文件备注")
private String remark;
}
controller
@PostMapping("media")
@Override
public MediaDTO saveMediaInfo(@RequestBody MediaVO mediaVO) {
//1.获取公司id
Long companyId = SecurityUtil.getCompanyId();
//2.将vo转成dto
MediaDTO dto = MediaConvert.INSTANCE.vo2dto(mediaVO);
return mediaService.saveMediaInfo(dto,companyId);
}
service
/**
* 1.检查关键数据
* 重要字段不能为空
* 2.校验业务数据
* 无需校验
* 3.将dto转为po插入数据库
* 设置auditStatus为未审核
* 4.查询数据转为dto返回
* @param dto
* @param companyId
* @return
*/
@Transactional
@Override
public MediaDTO saveMediaInfo(MediaDTO dto, Long companyId) {
//1.将dto转为po
Media media = MediaConvert.INSTANCE.dto2po(dto);
//2.为po设置额外信息:companyId和auditStatus
media.setCompanyId(companyId);
media.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
boolean save = this.save(media);
//插入失败则抛出异常
if(!save){
ExceptionCast.cast(MediaErrorCode.E_140001);
}
//3.从数据库中查询新插入的数据
Media byId = this.getById(media.getId());
MediaDTO mediaDTO = MediaConvert.INSTANCE.po2dto(byId);
return mediaDTO;
}
预览课程就是通过mediaId和companyName找到对应的媒资信息获得file_id,再用file_id向阿里云发送请求获得url
controller
@GetMapping("/media/preview/{mediaId}")
public String previewMedia(@PathVariable Long mediaId) {
Long companyId = SecurityUtil.getCompanyId();
String vodUrl = mediaService.getVODUrl(mediaId,companyId);
return vodUrl;
}
service
/**
* 1.关键数据校验
* mediaId不为null
* 2. 业务数据校验
* mediaId对应的media不为null
* companyId若存在则校验,若不存在则说明是运营方
* 3. 得到资源key后向阿里云发起请求获得视频url
*
* @param mediaId
* @param companyId
* @return
*/
@Override
public String getVODUrl(Long mediaId, Long companyId) {
//1.关键数据校验
// mediaId不为null
if(ObjectUtils.isEmpty(mediaId)){
ExceptionCast.cast(MediaErrorCode.E_140005);
}
//2. 业务数据校验
// mediaId对应的media不为null
Media media = this.getById(mediaId);
if(media == null){
ExceptionCast.cast(MediaErrorCode.E_140005);
}
//companyId若存在则校验,若不存在则说明是运营方
if (!(ObjectUtils.isEmpty(companyId))) {
if (!(ObjectUtils.nullSafeEquals(media.getCompanyId(), companyId))) {
ExceptionCast.cast(CommonErrorCode.E_100108);
}
}
//3.判断media的url是否存在
String playUrl = media.getUrl();
if(ObjectUtils.isEmpty(playUrl)) { //若不存在则向阿里云发送请求,得到url
playUrl = getPlayUrl(media.getFileId());
}
return playUrl;
}