| @@ -154,7 +154,7 @@ public class ShiroConfig { | |||||
| filterChainDefinitionMap.put("/logout", "authc"); | filterChainDefinitionMap.put("/logout", "authc"); | ||||
| filterChainDefinitionMap.put("/**", "corsFilter,token,authc"); | filterChainDefinitionMap.put("/**", "corsFilter,token,authc"); | ||||
| // filterChainDefinitionMap.put("/**", "anon"); | |||||
| filterChainDefinitionMap.put("/**", "anon"); | |||||
| shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); | ||||
| @@ -73,14 +73,6 @@ public class VideoController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| String videoType; | String videoType; | ||||
| @GetMapping("/test") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "title", value = "页数", dataType = "String", paramType = "query", required = true)}) | |||||
| public ResultData list(@ModelAttribute WxPropertyContract wxPropertyContract, String title) { | |||||
| VideUploadResult result = videoFactory.getExcutor(videoType).uploadLocalVideo("123123213", "C:\\Users\\xiaohu\\Desktop\\111.mp4"); | |||||
| return new ResultData(result); | |||||
| } | |||||
| /** | /** | ||||
| * 上传视频 | * 上传视频 | ||||
| * | * | ||||
| @@ -104,7 +96,7 @@ public class VideoController extends BaseController { | |||||
| if(!fileFormat.endsWith("mp4")){ | if(!fileFormat.endsWith("mp4")){ | ||||
| return new ResultData(ErrorCode.PICTURE_ENDWIDTH_ERROR); | return new ResultData(ErrorCode.PICTURE_ENDWIDTH_ERROR); | ||||
| } | } | ||||
| VideUploadResult result = videoFactory.getExcutor(videoType).uploadLocalVideo(title, multiReq.getInputStream(),fileFormat); | |||||
| VideUploadResult result = videoFactory.getExcutor(videoType).uploadVideoStream(title, multiReq.getInputStream(),fileFormat); | |||||
| return new ResultData(result); | return new ResultData(result); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error(e.getMessage()); | logger.error(e.getMessage()); | ||||
| @@ -132,5 +124,26 @@ public class VideoController extends BaseController { | |||||
| return new ResultData(ErrorCode.PICTURE_ANALYZING_ERROR); | return new ResultData(ErrorCode.PICTURE_ANALYZING_ERROR); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 上传视频 | |||||
| * | |||||
| * @param multiReq | |||||
| * @return | |||||
| * @throws Exception | |||||
| */ | |||||
| @GetMapping(value = "/videoContentLength") | |||||
| @ApiOperation("上传视频进度") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "videoId", value = "视频编号", dataType = "String", paramType = "query", required = true)}) | |||||
| public ResultData videoContentLength(String videoId) { | |||||
| try { | |||||
| String result = videoFactory.getExcutor(videoType).getVedioContentLength(videoId); | |||||
| return new ResultData(result); | |||||
| } catch (Exception e) { | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.PICTURE_ANALYZING_ERROR); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -172,6 +172,11 @@ video: | |||||
| accessKeyId: LTAI4G7ixY4AhvM35F8o3W3V | accessKeyId: LTAI4G7ixY4AhvM35F8o3W3V | ||||
| accessKeySecret: VfWqGb83qIQrS9us45utskl8itd7ry | accessKeySecret: VfWqGb83qIQrS9us45utskl8itd7ry | ||||
| regionId: cn-beijing | regionId: cn-beijing | ||||
| endPoint: https://oss-cn-beijing.aliyuncs.com | |||||
| corePoolSize: 6 | |||||
| maxPoolSize: 20 | |||||
| queueCapacity: 1000 | |||||
| namePrefix: aliyun-video-upload | |||||
| jasypt: | jasypt: | ||||
| @@ -14,8 +14,8 @@ spring: | |||||
| default-property-inclusion: non_null | default-property-inclusion: non_null | ||||
| servlet: | servlet: | ||||
| multipart: | multipart: | ||||
| max-file-size: 20MB | |||||
| max-request-size: 200MB | |||||
| max-file-size: 300MB | |||||
| max-request-size: 1024MB | |||||
| cache: | cache: | ||||
| type: REDIS | type: REDIS | ||||
| cache-names: redis_cache #缓存的名字(可以不指定) | cache-names: redis_cache #缓存的名字(可以不指定) | ||||
| @@ -8,50 +8,37 @@ | |||||
| <version>1.0</version> | <version>1.0</version> | ||||
| </parent> | </parent> | ||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| <artifactId>mallinkVideo</artifactId> | <artifactId>mallinkVideo</artifactId> | ||||
| <repositories> | |||||
| <repository> | |||||
| <id>sonatype-nexus-staging</id> | |||||
| <name>Sonatype Nexus Staging</name> | |||||
| <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> | |||||
| <releases> | |||||
| <enabled>true</enabled> | |||||
| </releases> | |||||
| <snapshots> | |||||
| <enabled>true</enabled> | |||||
| </snapshots> | |||||
| </repository> | |||||
| </repositories> | |||||
| <dependencies> | <dependencies> | ||||
| <dependency> | |||||
| <groupId>com.aliyun</groupId> | |||||
| <artifactId>aliyun-java-sdk-core</artifactId> | |||||
| <version>4.5.1</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.aliyun.oss</groupId> | |||||
| <artifactId>aliyun-sdk-oss</artifactId> | |||||
| <version>3.10.2</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.aliyun</groupId> | |||||
| <artifactId>aliyun-java-sdk-vod</artifactId> | |||||
| <version>2.15.11</version> | |||||
| </dependency> | |||||
| <!-- 引入外包 --> | |||||
| <!-- mvn install:install-file -Dfile=/lib/aliyun-java-vod-upload-1.4.14.jar -DgroupId=com.aliyun -DartifactId=aliyun-java-vod-upload -Dversion=1.4.14 -Dpackaging=jar --> | |||||
| <dependency> | |||||
| <groupId>com.aliyun</groupId> | |||||
| <artifactId>aliyun-java-vod-upload</artifactId> | |||||
| <version>1.4.14</version> | |||||
| <!-- <scope>system</scope> | |||||
| <systemPath>${basedir}/src/main/resources/lib/aliyun-java-vod-upload-1.4.14.jar</systemPath> --> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.alibaba</groupId> | |||||
| <artifactId>fastjson</artifactId> | |||||
| <version>1.2.62</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.json</groupId> | |||||
| <artifactId>json</artifactId> | |||||
| <version>20170516</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.google.code.gson</groupId> | |||||
| <artifactId>gson</artifactId> | |||||
| <version>2.8.2</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.aliyun</groupId> | |||||
| <artifactId>aliyun-java-sdk-core</artifactId> | |||||
| <version>4.5.1</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.aliyun</groupId> | |||||
| <artifactId>aliyun-java-sdk-vod</artifactId> | |||||
| <version>2.15.11</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.alibaba</groupId> | |||||
| <artifactId>fastjson</artifactId> | |||||
| <version>1.2.62</version> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| </project> | </project> | ||||
| @@ -11,14 +11,11 @@ public interface VideoExcutor { | |||||
| * 上传视频 | * 上传视频 | ||||
| * title:视频标题 | * title:视频标题 | ||||
| */ | */ | ||||
| public VideUploadResult uploadLocalVideo(String title,String localFile); | |||||
| public VideUploadResult uploadLocalVideo(String title,InputStream inputStream,String fileFormat); | |||||
| //ext,后缀名 | |||||
| public VideUploadResult uploadNetVideo(String title,String url,String ext); | |||||
| public VideUploadResult uploadVideoStream(String title,InputStream inputStream,String ex); | |||||
| public String getVedioUploadProgress(String videoId); | public String getVedioUploadProgress(String videoId); | ||||
| public String getVedioContentLength(String videoId); | |||||
| VideUploadResult getVideoDetail(String videoId); | VideUploadResult getVideoDetail(String videoId); | ||||
| } | } | ||||
| @@ -1,26 +1,28 @@ | |||||
| package com.iformall.video.aliyun; | package com.iformall.video.aliyun; | ||||
| import java.io.IOException; | |||||
| import java.io.File; | |||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.UUID; | import java.util.UUID; | ||||
| import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse; | |||||
| import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse; | import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse; | ||||
| import com.baomidou.mybatisplus.core.toolkit.IdWorker; | |||||
| import org.apache.commons.io.FileUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.beans.factory.annotation.Qualifier; | import org.springframework.beans.factory.annotation.Qualifier; | ||||
| import org.springframework.data.redis.core.RedisTemplate; | import org.springframework.data.redis.core.RedisTemplate; | ||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
| import com.aliyun.vod.upload.resp.UploadStreamResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadURLStreamResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadVideoResponse; | |||||
| import com.aliyuncs.DefaultAcsClient; | |||||
| import com.aliyuncs.exceptions.ClientException; | import com.aliyuncs.exceptions.ClientException; | ||||
| import com.aliyuncs.profile.DefaultProfile; | |||||
| import com.iformall.video.VideoExcutor; | import com.iformall.video.VideoExcutor; | ||||
| import com.iformall.video.aliyun.config.AliyunVideoConfig; | import com.iformall.video.aliyun.config.AliyunVideoConfig; | ||||
| import com.iformall.video.aliyun.sdk.server.AliyunVedioServer; | import com.iformall.video.aliyun.sdk.server.AliyunVedioServer; | ||||
| import com.iformall.video.aliyun.sdk.upload.AliyunVedioUpload; | |||||
| import com.iformall.video.aliyun.sdk.server.UploadCacheHelper; | |||||
| import com.iformall.video.aliyun.thread.AliyunVideoUploadThread; | |||||
| import com.iformall.video.entity.VideUploadResult; | import com.iformall.video.entity.VideUploadResult; | ||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
| @Component | @Component | ||||
| @@ -30,6 +32,9 @@ public class AliyunVideoExcutor implements VideoExcutor { | |||||
| @Autowired | @Autowired | ||||
| AliyunVideoConfig config; | AliyunVideoConfig config; | ||||
| @Autowired | |||||
| AliyunVideoUploadThread thread; | |||||
| @Autowired | @Autowired | ||||
| @Qualifier("objectCommonRedisTemplate") | @Qualifier("objectCommonRedisTemplate") | ||||
| RedisTemplate<String, Object> redisTemplate; | RedisTemplate<String, Object> redisTemplate; | ||||
| @@ -43,20 +48,35 @@ public class AliyunVideoExcutor implements VideoExcutor { | |||||
| return null; | return null; | ||||
| } | } | ||||
| public DefaultAcsClient initVodClient() throws ClientException { | |||||
| String regionId = config.getRegionId(); // 点播服务接入区域 | |||||
| DefaultProfile profile = DefaultProfile.getProfile(regionId, config.getAccessKeyId(), config.getAccessKeySecret()); | |||||
| DefaultAcsClient client = new DefaultAcsClient(profile); | |||||
| return client; | |||||
| } | |||||
| /** | |||||
| * https://help.aliyun.com/document_detail/61063.html?spm=a2c4g.11186623.6.1036.2f81d418ydqsX8 | |||||
| * https://help.aliyun.com/document_detail/55407.htm?spm=a2c4g.11186623.2.12.77aad4180Hg9y0#doc-api-vod-CreateUploadVideo | |||||
| */ | |||||
| @Override | @Override | ||||
| public VideUploadResult uploadLocalVideo(String title,String localFile) { | |||||
| public VideUploadResult uploadVideoStream(String title,InputStream inputStream,String ex) { | |||||
| VideUploadResult result = new VideUploadResult(); | VideUploadResult result = new VideUploadResult(); | ||||
| try { | try { | ||||
| UploadVideoResponse response =AliyunVedioUpload.uploadVideo(config.getAccessKeyId(), config.getAccessKeySecret(),config.getRegionId(), title, localFile,redisTemplate); | |||||
| if (response.isSuccess()) { | |||||
| result.setVideoId(response.getVideoId()); | |||||
| result.setVideoUrl(getUrlByVeidoId(response.getVideoId())); | |||||
| result.setSuccess(true); | |||||
| }else { | |||||
| //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 | |||||
| result.setSuccess(false); | |||||
| result.setMsg("ErrorCode["+response.getCode()+"]"+response.getMessage()); | |||||
| //该接口不会真正上传视频文件,您需要获得上传地址和凭证后,对其进行Base64解码,再调用OSS SDK将视频文件上传至指定的bucket中。详细操作,请参见基于OSS原生SDK上传视频到点播 | |||||
| File folder = new File ("/video/upload/temp/aliyun") ; | |||||
| if (!folder.exists()) { | |||||
| folder.mkdirs(); | |||||
| } | } | ||||
| String _tempfilepath = "/video/upload/temp/aliyun/"+IdWorker.get32UUID()+"."+ex; | |||||
| File targetFile = new File(_tempfilepath); | |||||
| FileUtils.copyInputStreamToFile(inputStream, targetFile); | |||||
| CreateUploadVideoResponse response =AliyunVedioServer.createUploadVideo(config, title, _tempfilepath); | |||||
| result.setVideoId(response.getVideoId()); | |||||
| //result.setVideoUrl(getUrlByVeidoId(response.getVideoId())); | |||||
| result.setSuccess(true); | |||||
| //TODO 线程池的方式 | |||||
| thread.executeAysncTask(response, _tempfilepath,redisTemplate); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| log.error("aliyun uploadLocalVideo error",e); | log.error("aliyun uploadLocalVideo error",e); | ||||
| result.setSuccess(false); | result.setSuccess(false); | ||||
| @@ -82,55 +102,9 @@ public class AliyunVideoExcutor implements VideoExcutor { | |||||
| } | } | ||||
| } | } | ||||
| @Override | |||||
| public VideUploadResult uploadLocalVideo(String title,InputStream inputStream,String fileFormat) { | |||||
| VideUploadResult result = new VideUploadResult(); | |||||
| UploadStreamResponse response; | |||||
| try { | |||||
| response = AliyunVedioUpload.uploadStream(config.getAccessKeyId(), config.getAccessKeySecret(),config.getRegionId(), title, UUID.randomUUID().toString().replace("-","")+fileFormat, inputStream,redisTemplate); | |||||
| if (response.isSuccess()) { | |||||
| result.setVideoId(response.getVideoId()); | |||||
| // setVideUploadResult(result,response.getVideoId()); | |||||
| result.setVideoUrl(getUrlByVeidoId(response.getVideoId())); | |||||
| result.setSuccess(true); | |||||
| } else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 | |||||
| result.setSuccess(false); | |||||
| result.setMsg("ErrorCode["+response.getCode()+"]"+response.getMessage()); | |||||
| } | |||||
| } catch (Exception e) { | |||||
| log.error("aliyun uploadLocalVideo error",e); | |||||
| result.setSuccess(false); | |||||
| result.setMsg(e.getLocalizedMessage()); | |||||
| }finally { | |||||
| if (null != inputStream) { | |||||
| try { | |||||
| inputStream.close(); | |||||
| } catch (IOException e) { | |||||
| } | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| @Override | |||||
| public VideUploadResult uploadNetVideo(String title,String url,String ext) { | |||||
| VideUploadResult result = new VideUploadResult(); | |||||
| UploadURLStreamResponse response = AliyunVedioUpload.uploadURLStream(config.getAccessKeyId(), config.getAccessKeySecret(),config.getRegionId(), title, url, ext,redisTemplate); | |||||
| if (response.isSuccess()) { | |||||
| result.setVideoId(response.getVideoId()); | |||||
| result.setVideoUrl(getUrlByVeidoId(response.getVideoId())); | |||||
| result.setSuccess(true); | |||||
| } else { | |||||
| /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */ | |||||
| result.setSuccess(false); | |||||
| result.setMsg("ErrorCode["+response.getCode()+"]"+response.getMessage()); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| @Override | @Override | ||||
| public String getVedioUploadProgress(String videoId) { | public String getVedioUploadProgress(String videoId) { | ||||
| return AliyunVedioUpload.getUploadProgress(redisTemplate, videoId); | |||||
| return UploadCacheHelper.getUploadProgress(redisTemplate, videoId); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -161,4 +135,9 @@ public class AliyunVideoExcutor implements VideoExcutor { | |||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| @Override | |||||
| public String getVedioContentLength(String videoId) { | |||||
| return UploadCacheHelper.getContentLength(redisTemplate, videoId); | |||||
| } | |||||
| } | } | ||||
| @@ -12,4 +12,5 @@ public class AliyunVideoConfig { | |||||
| private String accessKeyId; | private String accessKeyId; | ||||
| private String accessKeySecret; | private String accessKeySecret; | ||||
| private String regionId;//cn-shanghai 点播服务接入区域 | private String regionId;//cn-shanghai 点播服务接入区域 | ||||
| private String endPoint;//以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com | |||||
| } | } | ||||
| @@ -1,9 +1,26 @@ | |||||
| package com.iformall.video.aliyun.sdk.server; | package com.iformall.video.aliyun.sdk.server; | ||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.net.MalformedURLException; | |||||
| import java.net.URL; | |||||
| import java.util.Base64; | |||||
| import java.util.List; | import java.util.List; | ||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.aliyun.oss.OSS; | |||||
| import com.aliyun.oss.OSSClient; | |||||
| import com.aliyun.oss.OSSClientBuilder; | |||||
| import com.aliyun.oss.model.PutObjectRequest; | |||||
| import com.aliyuncs.DefaultAcsClient; | import com.aliyuncs.DefaultAcsClient; | ||||
| import com.aliyuncs.profile.DefaultProfile; | import com.aliyuncs.profile.DefaultProfile; | ||||
| import com.aliyuncs.vod.model.v20170321.CreateUploadVideoRequest; | |||||
| import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse; | |||||
| import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest; | import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest; | ||||
| import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse; | import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse; | ||||
| import com.iformall.video.aliyun.config.AliyunVideoConfig; | import com.iformall.video.aliyun.config.AliyunVideoConfig; | ||||
| @@ -22,6 +39,71 @@ public class AliyunVedioServer { | |||||
| return client; | return client; | ||||
| } | } | ||||
| /** | |||||
| * 获取视频上传地址和凭证 | |||||
| * @param client 发送请求客户端 | |||||
| * @return CreateUploadVideoResponse 获取视频上传地址和凭证响应数据 | |||||
| * @throws Exception | |||||
| */ | |||||
| public static CreateUploadVideoResponse createUploadVideo(AliyunVideoConfig config,String title,String fileName) throws Exception { | |||||
| DefaultAcsClient client = initVodClient(config); | |||||
| CreateUploadVideoRequest request = new CreateUploadVideoRequest(); | |||||
| request.setTitle(title); | |||||
| request.setFileName(fileName); | |||||
| //UserData,用户自定义设置参数,用户需要单独回调URL及数据透传时设置(非必须) | |||||
| //JSONObject userData = new JSONObject(); | |||||
| //UserData回调部分设置 | |||||
| //JSONObject messageCallback = new JSONObject(); | |||||
| //messageCallback.put("CallbackURL", "http://192.168.0.0/16"); | |||||
| //messageCallback.put("CallbackType", "http"); | |||||
| //userData.put("MessageCallback", messageCallback.toJSONString()); | |||||
| //UserData透传数据部分设置 | |||||
| //JSONObject extend = new JSONObject(); | |||||
| //extend.put("MyId", "user-defined-id"); | |||||
| //userData.put("Extend", extend.toJSONString()); | |||||
| //request.setUserData(userData.toJSONString()); | |||||
| return client.getAcsResponse(request); | |||||
| } | |||||
| private static OssUploadClient initOssClient(CreateUploadVideoResponse response) throws UnsupportedEncodingException { | |||||
| final Base64.Decoder decoder = Base64.getDecoder(); | |||||
| String uploadAddressStr = new String(decoder.decode(response.getUploadAddress().getBytes("UTF-8"))); | |||||
| String uploadAuthStr = new String(decoder.decode(response.getUploadAuth().getBytes("UTF-8"))); | |||||
| JSONObject uploadAuth = JSON.parseObject(uploadAuthStr); | |||||
| JSONObject uploadAddress = JSON.parseObject(uploadAddressStr); | |||||
| String bucket = uploadAddress.getString("Bucket"); | |||||
| String endpoint = uploadAddress.getString("Endpoint"); | |||||
| String fileName = uploadAddress.getString("FileName"); | |||||
| String accessKeyId = uploadAuth.getString("AccessKeyId"); | |||||
| String accessKeySecret = uploadAuth.getString("AccessKeySecret"); | |||||
| String securityToken = uploadAuth.getString("SecurityToken"); | |||||
| OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); | |||||
| return new OssUploadClient(bucket, endpoint, fileName, client); | |||||
| } | |||||
| public static void uploadVideo(CreateUploadVideoResponse response,String localFile,RedisTemplate<String, Object> redisTemplate) throws UnsupportedEncodingException { | |||||
| OssUploadClient ossClient = initOssClient(response); | |||||
| // 创建PutObjectRequest对象。 | |||||
| // 填写Bucket名称、Object完整路径和本地文件的完整路径。Object完整路径中不能包含Bucket名称。 | |||||
| // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。 | |||||
| //PutObjectRequest putObjectRequest = new PutObjectRequest(ossClient.getBucket(), ossClient.getFileName(), new File(localFile)); | |||||
| // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。 | |||||
| // ObjectMetadata metadata = new ObjectMetadata(); | |||||
| // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString()); | |||||
| // metadata.setObjectAcl(CannedAccessControlList.Private); | |||||
| // putObjectRequest.setMetadata(metadata); | |||||
| // 上传文件。 | |||||
| ossClient.getOssClient().putObject(new PutObjectRequest(ossClient.getBucket(), ossClient.getFileName(), new File(localFile)). | |||||
| <PutObjectRequest>withProgressListener(new PutObjectProgressListener(redisTemplate,response.getVideoId(),localFile))); | |||||
| // 关闭OSSClient。 | |||||
| ossClient.getOssClient().shutdown(); | |||||
| } | |||||
| //获取视频播放地址 | //获取视频播放地址 | ||||
| //https://help.aliyun.com/document_detail/61064.html?spm=a2c4g.11186623.6.1043.7c2d3838K6wQPZ | //https://help.aliyun.com/document_detail/61064.html?spm=a2c4g.11186623.6.1043.7c2d3838K6wQPZ | ||||
| public static String getVedioUrl(AliyunVideoConfig config,String videoId) throws ClientException { | public static String getVedioUrl(AliyunVideoConfig config,String videoId) throws ClientException { | ||||
| @@ -0,0 +1,16 @@ | |||||
| package com.iformall.video.aliyun.sdk.server; | |||||
| import com.aliyun.oss.OSS; | |||||
| import lombok.AllArgsConstructor; | |||||
| import lombok.Data; | |||||
| @Data | |||||
| @AllArgsConstructor | |||||
| public class OssUploadClient { | |||||
| private String bucket; | |||||
| private String endpoint; | |||||
| private String fileName; | |||||
| private OSS ossClient; | |||||
| } | |||||
| @@ -0,0 +1,90 @@ | |||||
| package com.iformall.video.aliyun.sdk.server; | |||||
| import java.io.File; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import com.aliyun.oss.event.ProgressEvent; | |||||
| import com.aliyun.oss.event.ProgressEventType; | |||||
| import com.aliyun.oss.event.ProgressListener; | |||||
| public class PutObjectProgressListener implements ProgressListener{ | |||||
| private String videoId = ""; | |||||
| private String localFile = ""; | |||||
| private long bytesWritten = 0; | |||||
| private long totalBytes = -1; | |||||
| private boolean succeed = false; | |||||
| private RedisTemplate<String, Object> redisTemplate; | |||||
| public PutObjectProgressListener(RedisTemplate<String, Object> redisTemplate,String videoId,String localFile) { | |||||
| this.redisTemplate = redisTemplate; | |||||
| this.videoId = videoId; | |||||
| this.localFile = localFile; | |||||
| } | |||||
| @Override | |||||
| public void progressChanged(ProgressEvent progressEvent) { | |||||
| long bytes = progressEvent.getBytes(); | |||||
| ProgressEventType eventType = progressEvent.getEventType(); | |||||
| switch (eventType) { | |||||
| case TRANSFER_STARTED_EVENT: | |||||
| if (null != redisTemplate && (!StringUtils.isBlank(videoId))) { | |||||
| UploadCacheHelper.cacheStart(redisTemplate, videoId); | |||||
| } | |||||
| //System.out.println("Start to upload......"); | |||||
| break; | |||||
| case REQUEST_CONTENT_LENGTH_EVENT: | |||||
| this.totalBytes = bytes; | |||||
| if (null != redisTemplate && (!StringUtils.isBlank(videoId))) { | |||||
| UploadCacheHelper.setContentLength(redisTemplate, videoId, String.valueOf(this.totalBytes)); | |||||
| } | |||||
| //System.out.println(this.totalBytes + " bytes in total will be uploaded to OSS"); | |||||
| break; | |||||
| case REQUEST_BYTE_TRANSFER_EVENT: | |||||
| this.bytesWritten += bytes; | |||||
| if (this.totalBytes != -1) { | |||||
| int percent = (int)(this.bytesWritten * 100.0 / this.totalBytes); | |||||
| //System.out.println(bytes + " bytes have been written at this time, upload progress: " + percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")"); | |||||
| } else { | |||||
| //System.out.println(bytes + " bytes have been written at this time, upload ratio: unknown" + "(" + this.bytesWritten + "/...)"); | |||||
| } | |||||
| if (null != redisTemplate && (!StringUtils.isBlank(videoId))) { | |||||
| UploadCacheHelper.cacheProgress(redisTemplate, videoId, String.valueOf(this.bytesWritten)); | |||||
| } | |||||
| break; | |||||
| case TRANSFER_COMPLETED_EVENT: | |||||
| this.succeed = true; | |||||
| if (null != redisTemplate && (!StringUtils.isBlank(videoId))) { | |||||
| UploadCacheHelper.cacheComplete(redisTemplate, videoId); | |||||
| } | |||||
| if (!StringUtils.isBlank(localFile)) { | |||||
| File f = new File(localFile); | |||||
| if (f.exists()) { | |||||
| f.delete(); | |||||
| } | |||||
| } | |||||
| //System.out.println("Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total"); | |||||
| break; | |||||
| case TRANSFER_FAILED_EVENT: | |||||
| //System.out.println("Failed to upload, " + this.bytesWritten + " bytes have been transferred"); | |||||
| if (null != redisTemplate && (!StringUtils.isBlank(videoId))) { | |||||
| UploadCacheHelper.cacheError(redisTemplate, videoId); | |||||
| } | |||||
| if (!StringUtils.isBlank(localFile)) { | |||||
| File f = new File(localFile); | |||||
| if (f.exists()) { | |||||
| f.delete(); | |||||
| } | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| public boolean isSucceed() { | |||||
| return succeed; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| package com.iformall.video.aliyun.sdk.server; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import org.springframework.data.redis.core.ValueOperations; | |||||
| public class UploadCacheHelper { | |||||
| private static String PRE = "video:upload:aliyun:progress:"; | |||||
| public static void cacheStart(RedisTemplate<String, Object> template,String videoId) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(PRE+videoId, "begin", 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static void cacheComplete(RedisTemplate<String, Object> template,String videoId) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(PRE+videoId, "complete", 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static void cacheProgress(RedisTemplate<String, Object> template,String videoId,String bytes) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(PRE+videoId, bytes, 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static void cacheError(RedisTemplate<String, Object> template,String videoId) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(PRE+videoId, "error", 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static String getUploadProgress(RedisTemplate<String, Object> template,String videoId) { | |||||
| if (template.hasKey(PRE+videoId)) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| Object o = operations.get(PRE+videoId); | |||||
| if (o instanceof String) { | |||||
| return (String)o; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public static void setContentLength(RedisTemplate<String, Object> template,String videoId,String length) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set("video:upload:aliyun:contengLength:"+videoId, length, 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static String getContentLength(RedisTemplate<String, Object> template,String videoId) { | |||||
| if (template.hasKey("video:upload:aliyun:contengLength:"+videoId)) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| Object o = operations.get("video:upload:aliyun:contengLength:"+videoId); | |||||
| if (o instanceof String) { | |||||
| return (String)o; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -1,695 +0,0 @@ | |||||
| package com.iformall.video.aliyun.sdk.upload; | |||||
| import java.io.FileInputStream; | |||||
| import java.io.FileNotFoundException; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.net.URL; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import com.aliyun.vod.upload.impl.UploadAttachedMediaImpl; | |||||
| import com.aliyun.vod.upload.impl.UploadImageImpl; | |||||
| import com.aliyun.vod.upload.impl.UploadM3u8FileImpl; | |||||
| import com.aliyun.vod.upload.impl.UploadVideoImpl; | |||||
| import com.aliyun.vod.upload.req.UploadAttachedMediaRequest; | |||||
| import com.aliyun.vod.upload.req.UploadFileStreamRequest; | |||||
| import com.aliyun.vod.upload.req.UploadImageRequest; | |||||
| import com.aliyun.vod.upload.req.UploadLocalM3u8Request; | |||||
| import com.aliyun.vod.upload.req.UploadStreamRequest; | |||||
| import com.aliyun.vod.upload.req.UploadURLStreamRequest; | |||||
| import com.aliyun.vod.upload.req.UploadVideoRequest; | |||||
| import com.aliyun.vod.upload.req.UploadWebM3u8Request; | |||||
| import com.aliyun.vod.upload.resp.UploadAttachedMediaResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadFileStreamResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadImageResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadLocalM3u8Response; | |||||
| import com.aliyun.vod.upload.resp.UploadStreamResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadURLStreamResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadVideoResponse; | |||||
| import com.aliyun.vod.upload.resp.UploadWebM3u8Response; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| /** | |||||
| * 以下Java示例代码演示了如何在服务端上传媒资文件至视频点播,媒资类型支持音频、视频和图片。 | |||||
| * <p> | |||||
| * 一、音视频上传目前支持4种方式上传: | |||||
| * | |||||
| * 1.上传本地文件,使用分片上传,并支持断点续传,参见testUploadVideo函数。 | |||||
| * 1.1 当断点续传关闭时,最大支持上传任务执行时间为3000秒,具体可上传文件大小与您的网络带宽及磁盘读写能力有关。 | |||||
| * 1.2 当断点续传开启时,最大支持48.8TB的单个文件,注意,断点续传开启后,上传任务执行过程中,同时会将当前上传位置写入本地磁盘文件,影响您上传文件的速度,请您根据文件大小选择是否开启 | |||||
| * | |||||
| * 2.上传网络流,可指定文件URL进行上传,支持断点续传,最大支持48.8TB的单个文件。 | |||||
| * 该上传方式需要先将网络文件下载到本地磁盘,再进行上传,所以要保证本地磁盘有充足的空间。参见testUploadURLStream函数。 | |||||
| * | |||||
| * 3.上传文件流,可指定本地文件进行上传,不支持断点续传,最大支持5GB的单个文件。参见testUploadFileStream函数。 | |||||
| * | |||||
| * 4.流式上传,可指定输入流进行上传,支持文件流和网络流等,不支持断点续传,最大支持5GB的单个文件。参见testUploadStream函数。 | |||||
| * <p> | |||||
| * | |||||
| * 二、图片上传目前支持2种方式上传: | |||||
| * 1.上传本地文件,不支持断点续传,最大支持5GB的单个文件,参见testUploadImageLocalFile函数 | |||||
| * 2.上传文件流和网络流,InputStream参数必选,不支持断点续传,最大支持5GB的单个文件。参见testUploadImageStream函数。 | |||||
| * 注:图片上传完成后,会返回图片ID和图片地址,也可通过GetImageInfo查询图片信息,参见接口文档 https://help.aliyun.com/document_detail/89742.html | |||||
| * <p> | |||||
| * | |||||
| * 三、m3u8文件上传目前支持2种方式: | |||||
| * 1.上传本地m3u8音视频文件(包括所有分片文件)到点播,需指定本地m3u8索引文件地址和所有分片地址。 | |||||
| * 2.上传网络m3u8音视频文件(包括所有分片文件)到点播,需指定m3u8索引文件和分片文件的URL地址。 | |||||
| * | |||||
| * 注: | |||||
| * 1) 上传网络m3u8音视频文件时需要保证地址可访问,如果有权限限制,请设置带签名信息的地址,且保证足够长的有效期,防止地址无法访问导致上传失败 | |||||
| * 2) m3u8文件上传暂不支持进度回调 | |||||
| * <p> | |||||
| * | |||||
| * 四、上传进度回调通知: | |||||
| * 1.默认上传进度回调函数:视频点播上传SDK内部默认开启上传进度回调函数,输出不同事件通知的日志,您可以设置关闭该上传进度通知及日志输出; | |||||
| * 2.自定义上传进度回调函数:您可根据自已的业务场景重新定义不同事件处理的方式,只需要修改上传回调示例函数即可。 | |||||
| * <p> | |||||
| * | |||||
| * 五、辅助媒资上传目前支持2种方式: | |||||
| * 1.上传本地文件,不支持断点续传,最大支持5GB的单个文件,参见testUploadAttachedMediaLocalFile函数 | |||||
| * 2.上传文件流和网络流,InputStream参数必选,不支持断点续传,最大支持5GB的单个文件。参见testUploadAttachedMediaStream函数。 | |||||
| * <p> | |||||
| * | |||||
| * 六、支持STS方式上传: | |||||
| * 1.您需要实现VoDRefreshSTSTokenListener接口的onRefreshSTSToken方法,用于生成STS信息, | |||||
| * 当文件上传时间超过STS过期时间时,SDK内部会定期调用此方法刷新您的STS信息进行后续文件的上传。 | |||||
| * <p> | |||||
| * | |||||
| * 七、可指定上传脚本部署的ECS区域(设置Request的EcsRegionId参数,取值参考存储区域标识:https://help.aliyun.com/document_detail/98194.html), | |||||
| * 如果与点播存储(OSS)区域相同,则自动使用内网上传文件至存储,上传更快且更省公网流量 | |||||
| * 由于点播API只提供外网域名访问,因此部署上传脚本的ECS服务器必须具有访问外网的权限。 | |||||
| * | |||||
| * 注意: | |||||
| * 请替换示例中的必选参数,示例中的可选参数如果您不需要设置,请将其删除,以免设置无效参数值与您的预期不符。 | |||||
| */ | |||||
| @Slf4j | |||||
| public class AliyunVedioUpload { | |||||
| public static void main(String[] args) { | |||||
| //账号AK信息请填写(必选) | |||||
| String accessKeyId = "<Your accessKeyId>"; | |||||
| //账号AK信息请填写(必选) | |||||
| String accessKeySecret = "<Your accessKeySecret>"; | |||||
| // 一、视频文件上传 | |||||
| // 视频标题(必选) | |||||
| String title = "测试标题"; | |||||
| // 1.本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选) | |||||
| // 2.网络流上传时,文件名称为源文件名,如文件名称.mp4(必选)。 | |||||
| // 3.流式上传时,文件名称为源文件名,如文件名称.mp4(必选)。 | |||||
| // 任何上传方式文件名必须包含扩展名 | |||||
| String fileName = "/Users/test/video/test.mp4"; | |||||
| // 本地文件上传 | |||||
| uploadVideo(accessKeyId, accessKeySecret,"cn-beijing", title, fileName,null); | |||||
| // 待上传视频的网络流地址 | |||||
| String url = "http://test.aliyun.com/video/test.mp4"; | |||||
| // 2.网络流上传 | |||||
| // 文件扩展名,当url中不包含扩展名时,需要设置该参数 | |||||
| String fileExtension = "mp4"; | |||||
| uploadURLStream(accessKeyId, accessKeySecret, "cn-beijing",title, url, fileExtension,null); | |||||
| // 3.文件流上传 | |||||
| // testUploadFileStream(accessKeyId, accessKeySecret, title, fileName); | |||||
| // 4.流式上传,如文件流和网络流 | |||||
| InputStream inputStream = null; | |||||
| // 4.1 文件流 | |||||
| try { | |||||
| inputStream = new FileInputStream(fileName); | |||||
| } catch (FileNotFoundException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| // 4.2 网络流 | |||||
| try { | |||||
| inputStream = new URL(url).openStream(); | |||||
| } catch (IOException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| uploadStream(accessKeyId, accessKeySecret, "cn-beijing",title, fileName, inputStream,null); | |||||
| // 二、图片上传 | |||||
| // 1.图片上传-本地文件上传 | |||||
| // testUploadImageLocalFile(accessKeyId, accessKeySecret); | |||||
| // 2.图片上传-流式上传(文件流和网络流) | |||||
| // testUploadImageStream(accessKeyId, accessKeySecret); | |||||
| // 三、m3u8文件上传 | |||||
| // 1.上传本地m3u8音视频文件 | |||||
| uploadLocalM3u8(accessKeyId, accessKeySecret,"cn-beijing"); | |||||
| // 2.上传网络m3u8音视频文件 | |||||
| uploadWebM3u8(accessKeyId, accessKeySecret,"cn-beijing"); | |||||
| // 四、辅助媒资上传 | |||||
| // 辅助媒资-本地文件上传 | |||||
| // testUploadAttachedMediaLocalFile(accessKeyId, accessKeySecret); | |||||
| // 辅助媒资-流式上传(文件流和网络流) | |||||
| // testUploadAttachedMediaStream(accessKeyId, accessKeySecret); | |||||
| } | |||||
| /** | |||||
| * 本地文件上传接口 | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| * @param title | |||||
| * @param fileName | |||||
| */ | |||||
| public static UploadVideoResponse uploadVideo(String accessKeyId, String accessKeySecret,String regionId, String title, String fileName, | |||||
| RedisTemplate<String, Object> redisTemplate) { | |||||
| UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName); | |||||
| /* 可指定分片上传时每个分片的大小,默认为2M字节 */ | |||||
| request.setPartSize(2 * 1024 * 1024L); | |||||
| /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/ | |||||
| request.setTaskNum(1); | |||||
| /* 是否开启断点续传, 默认断点续传功能关闭。当网络不稳定或者程序崩溃时,再次发起相同上传请求,可以继续未完成的上传任务,适用于超时3000秒仍不能上传完成的大文件。 | |||||
| 注意: 断点续传开启后,会在上传过程中将上传位置写入本地磁盘文件,影响文件上传速度,请您根据实际情况选择是否开启*/ | |||||
| //request.setEnableCheckpoint(false); | |||||
| /* OSS慢请求日志打印超时时间,是指每个分片上传时间超过该阈值时会打印debug日志,如果想屏蔽此日志,请调整该阈值。单位: 毫秒,默认为300000毫秒*/ | |||||
| //request.setSlowRequestsThreshold(300000L); | |||||
| /* 可指定每个分片慢请求时打印日志的时间阈值,默认为300s*/ | |||||
| //request.setSlowRequestsThreshold(300000L); | |||||
| /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/ | |||||
| //request.setIsShowWaterMark(true); | |||||
| /* 自定义消息回调设置(可选),参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}"); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(0); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 开启默认上传进度回调 */ | |||||
| request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置您实现的生成STS信息的接口实现类*/ | |||||
| // request.setVoDRefreshSTSTokenListener(new RefreshSTSTokenImpl()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| request.setEcsRegionId(regionId); | |||||
| UploadVideoImpl uploader = new UploadVideoImpl(); | |||||
| UploadVideoResponse response = uploader.uploadVideo(request); | |||||
| return response; | |||||
| } | |||||
| /** | |||||
| * URL网络流上传。支持断点续传,最大支持48.8TB的单个文件。 | |||||
| * 该上传方式需要先将网络文件下载到本地磁盘,再进行上传,所以要保证本地磁盘有充足的空间。 | |||||
| * 当您设置的URL中不包括文件扩展名时,需要单独设置fileExtension,表示文件扩展名。 | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| * @param title | |||||
| * @param fileName | |||||
| * @param url | |||||
| */ | |||||
| public static UploadURLStreamResponse uploadURLStream(String accessKeyId, String accessKeySecret,String regionId, String title, | |||||
| String url, String fileExtension,RedisTemplate<String, Object> redisTemplate) { | |||||
| UploadURLStreamRequest request = new UploadURLStreamRequest(accessKeyId, accessKeySecret, title, url); | |||||
| /* 文件扩展名*/ | |||||
| request.setFileExtension(fileExtension); | |||||
| /* 网络文件下载连接超时,单位毫秒,0-表示不限制*/ | |||||
| request.setDownloadConnectTimeout(1000); | |||||
| /* 网络文件下载读取超时,单位毫秒,0-表示不限制*/ | |||||
| request.setDownloadReadTimeout(0); | |||||
| /* 网络文件下载后保存的本地目录*/ | |||||
| request.setLocalDownloadFilePath("/aliyunvideo/download"); | |||||
| /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/ | |||||
| //request.setShowWaterMark(true); | |||||
| /* 自定义消息回调设置(可选),参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}"); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(0); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 开启默认上传进度回调 */ | |||||
| request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| request.setEcsRegionId(regionId); | |||||
| UploadVideoImpl uploader = new UploadVideoImpl(); | |||||
| UploadURLStreamResponse response = uploader.uploadURLStream(request); | |||||
| return response; | |||||
| } | |||||
| /** | |||||
| * 文件流上传接口 | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| * @param title | |||||
| * @param fileName | |||||
| */ | |||||
| private static void uploadFileStream(String accessKeyId, String accessKeySecret,String regionId, String title, String fileName, | |||||
| RedisTemplate<String, Object> redisTemplate) { | |||||
| UploadFileStreamRequest request = new UploadFileStreamRequest(accessKeyId, accessKeySecret, title, fileName); | |||||
| /* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/ | |||||
| //request.setShowWaterMark(true); | |||||
| /* 自定义消息回调设置,参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| //request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}""); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(0); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 开启默认上传进度回调 */ | |||||
| request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| request.setEcsRegionId(regionId); | |||||
| UploadVideoImpl uploader = new UploadVideoImpl(); | |||||
| UploadFileStreamResponse response = uploader.uploadFileStream(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"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 流式上传接口 | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| * @param title | |||||
| * @param fileName | |||||
| * @param inputStream | |||||
| */ | |||||
| public static UploadStreamResponse uploadStream(String accessKeyId, String accessKeySecret,String regionId, String title, | |||||
| String fileName, InputStream inputStream,RedisTemplate<String, Object> redisTemplate) { | |||||
| UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream); | |||||
| /* 是否使用默认水印(可选),指定模板组ID时,根据模板组配置确定是否使用默认水印*/ | |||||
| //request.setShowWaterMark(true); | |||||
| /* 自定义消息回调设置,参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| //request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}""); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(0); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 开启默认上传进度回调 */ | |||||
| // request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| // request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| // request.setEcsRegionId(regionId); | |||||
| UploadVideoImpl uploader = new UploadVideoImpl(); | |||||
| UploadStreamResponse response = uploader.uploadStream(request); | |||||
| return response; | |||||
| } | |||||
| /** | |||||
| * 图片上传接口,本地文件上传示例 | |||||
| * 参数参考文档 https://help.aliyun.com/document_detail/55619.html | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| */ | |||||
| public static void uploadImageLocalFile(String accessKeyId, String accessKeySecret,String regionId,RedisTemplate<String, Object> redisTemplate) { | |||||
| /* 图片类型(必选)取值范围:default(默认),cover(封面),watermark(水印)*/ | |||||
| String imageType = "cover"; | |||||
| UploadImageRequest request = new UploadImageRequest(accessKeyId, accessKeySecret, imageType); | |||||
| request.setImageType("cover"); | |||||
| /* 图片文件扩展名(可选)取值范围:png,jpg,jpeg */ | |||||
| //request.setImageExt("png"); | |||||
| /* 图片标题(可选)长度不超过128个字节,UTF8编码 */ | |||||
| //request.setTitle("图片标题"); | |||||
| /* 图片标签(可选)单个标签不超过32字节,最多不超过16个标签,多个用逗号分隔,UTF8编码 */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 存储区域(可选)*/ | |||||
| //request.setStorageLocation("out-4f3952f78c0211e8b3020013e7.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 流式上传时,InputStream为必选,fileName为源文件名称,如:文件名称.png(可选)*/ | |||||
| String fileName = "/Users/demo/png/test.png"; | |||||
| request.setFileName(fileName); | |||||
| /* 开启默认上传进度回调 */ | |||||
| request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| UploadImageImpl uploadImage = new UploadImageImpl(); | |||||
| UploadImageResponse response = uploadImage.upload(request); | |||||
| System.out.print("RequestId=" + response.getRequestId() + "\n"); | |||||
| if (response.isSuccess()) { | |||||
| System.out.print("ImageId=" + response.getImageId() + "\n"); | |||||
| System.out.print("ImageURL=" + response.getImageURL() + "\n"); | |||||
| } else { | |||||
| System.out.print("ErrorCode=" + response.getCode() + "\n"); | |||||
| System.out.print("ErrorMessage=" + response.getMessage() + "\n"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 图片上传接口,流式上传示例(支持文件流和网络流) | |||||
| * 参数参考文档 https://help.aliyun.com/document_detail/55619.html | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| */ | |||||
| public static void uploadImageStream(String accessKeyId, String accessKeySecret,String regionId,RedisTemplate<String, Object> redisTemplate) { | |||||
| /* 图片类型(必选)取值范围:default(默认),cover(封面),watermark(水印)*/ | |||||
| String imageType = "cover"; | |||||
| UploadImageRequest request = new UploadImageRequest(accessKeyId, accessKeySecret, imageType); | |||||
| /* 图片文件扩展名(可选)取值范围:png,jpg,jpeg */ | |||||
| //request.setImageExt("png"); | |||||
| /* 图片标题(可选)长度不超过128个字节,UTF8编码 */ | |||||
| //request.setTitle("图片标题"); | |||||
| /* 图片标签(可选)单个标签不超过32字节,最多不超过16个标签,多个用逗号分隔,UTF8编码 */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 存储区域(可选)*/ | |||||
| //request.setStorageLocation("out-4f3952f78c0211e8b3020013e7.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 流式上传时,InputStream为必选,fileName为源文件名称,如:文件名称.png(可选)*/ | |||||
| //request.setFileName("测试文件名称.png"); | |||||
| /* 开启默认上传进度回调 */ | |||||
| request.setPrintProgress(true); | |||||
| /* 设置自定义上传进度回调 (必须继承 VoDProgressListener) */ | |||||
| request.setProgressListener(new PutObjectProgressListener()); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| // 1.文件流上传 | |||||
| // InputStream fileStream = getFileStream(request.getFileName()); | |||||
| // if (fileStream != null) { | |||||
| // request.setInputStream(fileStream); | |||||
| // } | |||||
| // 2.网络流上传 | |||||
| String url = "http://test.aliyun.com/image/default/test.png"; | |||||
| InputStream urlStream = getUrlStream(url); | |||||
| if (urlStream != null) { | |||||
| request.setInputStream(urlStream); | |||||
| } | |||||
| // 开始上传图片 | |||||
| UploadImageImpl uploadImage = new UploadImageImpl(); | |||||
| UploadImageResponse response = uploadImage.upload(request); | |||||
| System.out.print("RequestId=" + response.getRequestId() + "\n"); | |||||
| if (response.isSuccess()) { | |||||
| System.out.print("ImageId=" + response.getImageId() + "\n"); | |||||
| System.out.print("ImageURL=" + response.getImageURL() + "\n"); | |||||
| } else { | |||||
| System.out.print("ErrorCode=" + response.getCode() + "\n"); | |||||
| System.out.print("ErrorMessage=" + response.getMessage() + "\n"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 上传本地m3u8视频或音频文件到点播,m3u8文件和分片文件默认在同一目录(sliceFilenames为空时,会按照同一目录去解析分片地址) | |||||
| * | |||||
| * @param request 本地m3u8上传请求类 | |||||
| * m3u8Filename: 本地m3u8索引文件的绝对路径,且m3u8文件的分片信息必须是相对路径,不能含有URL或本地绝对路径 | |||||
| * sliceFilenames: ts分片文件的绝对路径列表,如指定则以此为准,若不指定,则自动解析 m3u8Filename 里的m3u8文件 | |||||
| */ | |||||
| public static void uploadLocalM3u8(String accessKeyId, String accessKeySecret,String regionId) { | |||||
| String title = "test_upload_local_m3u8"; | |||||
| String m3u8Filename = "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/cc38da35c7b24de0abe58619cdd7a8-6479a12446b994719838e0307f6458-ld.m3u8"; | |||||
| UploadLocalM3u8Request request = new UploadLocalM3u8Request(accessKeyId, accessKeySecret, title, m3u8Filename); | |||||
| String[] sliceFilenames = new String[]{ | |||||
| "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a84937034742-ld-00001.ts", | |||||
| "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a84937034742-ld-00002.ts", | |||||
| "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a84937034742-ld-00003.ts", | |||||
| "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a84937034742-ld-00004.ts", | |||||
| "/Users/test/0e9ecfc6da934d1887ed7bdfc925ecf5/slices/cc38da35c7b24de0abe58619cdd7a896-c45797a1ad6e75fbb9d1a84937034742-ld-00005.ts" | |||||
| }; | |||||
| // ts分片文件列表,可选,不指定时,直接解析m3u8FileURL获取分片地址 | |||||
| request.setSliceFilenames(sliceFilenames); | |||||
| /* 可指定分片上传时每个分片的大小,默认为2M字节 */ | |||||
| request.setPartSize(2 * 1024 * 1024L); | |||||
| /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/ | |||||
| request.setTaskNum(1); | |||||
| /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/ | |||||
| //request.getShowWaterMark(true); | |||||
| /* 自定义消息回调设置(可选),参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}"); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(-1L); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 设置应用ID*/ | |||||
| // request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| request.setEcsRegionId(regionId); | |||||
| UploadM3u8FileImpl uploadM3u8File = new UploadM3u8FileImpl(); | |||||
| UploadLocalM3u8Response uploadLocalM3u8Response = uploadM3u8File.uploadLocalM3u8(request); | |||||
| System.out.println("code = " + uploadLocalM3u8Response.getCode()); | |||||
| System.out.println("message = " + uploadLocalM3u8Response.getMessage()); | |||||
| System.out.println("videoId = " + uploadLocalM3u8Response.getVideoId()); | |||||
| System.out.println("requestId = " + uploadLocalM3u8Response.getRequestId()); | |||||
| } | |||||
| /** | |||||
| * 上传网络m3u8视频或音频文件到点播,需本地磁盘空间足够,会先下载到本地临时目录,再上传到点播存储 | |||||
| * | |||||
| * @param request 网络m3u8上传请求类 | |||||
| * m3u8FileURL: 网络m3u8索引文件的URL地址,且m3u8文件的分片信息必须是相对地址,不能含有URL或本地绝对路径 | |||||
| * sliceFileURLs: ts分片文件的URL地址列表;需自行拼接ts分片的URL地址列表 | |||||
| */ | |||||
| public static void uploadWebM3u8(String accessKeyId, String accessKeySecret,String regionId) { | |||||
| String title = "test_upload_web_m3u8"; | |||||
| String m3u8FileURL = "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-538087dcf2c201c31ce4324bf76af691-ld.m3u8"; | |||||
| UploadWebM3u8Request request = new UploadWebM3u8Request(accessKeyId, accessKeySecret, title, m3u8FileURL); | |||||
| String[] sliceFileURLs = new String[]{ | |||||
| "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-00001.ts", | |||||
| "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-00002.ts", | |||||
| "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-00003.ts", | |||||
| "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-00004.ts", | |||||
| "http://test.aliyun.com/f0d644abc547129e957b386f772c72/a0e1e2817ab9425aa558fe67a90e717f-822598b9c170a8c6dad985e20cd9c27d-ld-00005.ts" | |||||
| }; | |||||
| // ts分片地址,可选,不指定时,直接解析m3u8FileURL获取分片地址 | |||||
| request.setSliceFileURLs(sliceFileURLs); | |||||
| /* 下载文件的临时存储目录,可自定义,如不指定则保存到程序所运行的目录下*/ | |||||
| // request.setGlobalLocalFilePath("/User/download/"); | |||||
| /* 可指定分片上传时每个分片的大小,默认为2M字节 */ | |||||
| request.setPartSize(2 * 1024 * 1024L); | |||||
| /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/ | |||||
| request.setTaskNum(1); | |||||
| /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/ | |||||
| //request.setShowWaterMark(true); | |||||
| /* 自定义消息回调设置(可选),参数说明参考文档 https://help.aliyun.com/document_detail/86952.html#UserData */ | |||||
| //request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://test.test.com\"}}"); | |||||
| /* 视频分类ID(可选) */ | |||||
| //request.setCateId(-1L); | |||||
| /* 视频标签,多个用逗号分隔(可选) */ | |||||
| //request.setTags("标签1,标签2"); | |||||
| /* 视频描述(可选) */ | |||||
| //request.setDescription("视频描述"); | |||||
| /* 封面图片(可选) */ | |||||
| //request.setCoverURL("http://cover.sample.com/sample.jpg"); | |||||
| /* 模板组ID(可选) */ | |||||
| //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e56a33d"); | |||||
| /* 工作流ID(可选) */ | |||||
| //request.setWorkflowId("d4430d07361f0*be1339577859b0177b"); | |||||
| /* 存储区域(可选) */ | |||||
| //request.setStorageLocation("in-201703232118266-5sejdln9o.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* ECS部署区域*/ | |||||
| request.setEcsRegionId(regionId); | |||||
| UploadM3u8FileImpl uploadM3u8File = new UploadM3u8FileImpl(); | |||||
| UploadWebM3u8Response uploadWebM3u8Response = uploadM3u8File.uploadWebM3u8(request); | |||||
| System.out.println("code = " + uploadWebM3u8Response.getCode()); | |||||
| System.out.println("message = " + uploadWebM3u8Response.getMessage()); | |||||
| System.out.println("videoId = " + uploadWebM3u8Response.getVideoId()); | |||||
| System.out.println("requestId = " + uploadWebM3u8Response.getRequestId()); | |||||
| } | |||||
| /** | |||||
| * 辅助媒资上传接口,本地文件上传示例 | |||||
| * 参数参考文档 https://help.aliyun.com/document_detail/98467.html | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| */ | |||||
| public static void uploadAttachedMediaLocalFile(String accessKeyId, String accessKeySecret,String regionId) { | |||||
| /* 业务类型 */ | |||||
| String businessType = "watermark"; | |||||
| /* 文件扩展名 */ | |||||
| String mediaExt = "png"; | |||||
| String filename = "/Users/demo/png/test.png"; | |||||
| UploadAttachedMediaRequest request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt); | |||||
| request.setFileName(filename); | |||||
| /* 标题*/ | |||||
| request.setTitle("test_attached_media"); | |||||
| /* 分类ID */ | |||||
| request.setCateId(-1L); | |||||
| /* 标签,多个用逗号分隔(可选) */ | |||||
| request.setTags("tag1,tag2"); | |||||
| /* 描述(可选) */ | |||||
| request.setDescription("test_desc"); | |||||
| /* 存储区域(可选) */ | |||||
| request.setStorageLocation("out-20170323225118266-5l3hs5gqwa.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* 设置应用ID*/ | |||||
| //request.setAppId("app-1000000"); | |||||
| UploadAttachedMediaImpl uploader = new UploadAttachedMediaImpl(); | |||||
| UploadAttachedMediaResponse response = uploader.upload(request); | |||||
| System.out.print("RequestId=" + response.getRequestId() + "\n"); | |||||
| if (response.isSuccess()) { | |||||
| System.out.print("MediaId=" + response.getMediaId() + "\n"); | |||||
| System.out.print("MediaURL=" + response.getMediaURL() + "\n"); | |||||
| System.out.print("FileURL=" + response.getFileURL() + "\n"); | |||||
| } else { | |||||
| System.out.print("ErrorCode=" + response.getCode() + "\n"); | |||||
| System.out.print("ErrorMessage=" + response.getMessage() + "\n"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 辅助媒资上传接口,流式上传示例(支持文件流和网络流) | |||||
| * 参数参考文档 https://help.aliyun.com/document_detail/98467.html | |||||
| * | |||||
| * @param accessKeyId | |||||
| * @param accessKeySecret | |||||
| */ | |||||
| public static void uploadAttachedMediaStream(String accessKeyId, String accessKeySecret,String regionId) { | |||||
| /* 业务类型 */ | |||||
| String businessType = "watermark"; | |||||
| /* 文件扩展名 */ | |||||
| String mediaExt = "png"; | |||||
| String filename = "http://test.aliyun.com/test.png"; | |||||
| UploadAttachedMediaRequest request; | |||||
| // 1.文件流上传 | |||||
| InputStream fileStream = getFileStream(filename); | |||||
| request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt); | |||||
| request.setInputStream(fileStream); | |||||
| // 2.网络流上传 | |||||
| // String url = "http://test.aliyun.com/image//test.png"; | |||||
| // InputStream urlStream = getUrlStream(url); | |||||
| // request = new UploadAttachedMediaRequest(accessKeyId, accessKeySecret, businessType, mediaExt); | |||||
| // request.setInputStream(urlStream); | |||||
| /* 标题*/ | |||||
| request.setTitle("test_attached_media"); | |||||
| /* 分类ID */ | |||||
| request.setCateId(-1L); | |||||
| /* 标签,多个用逗号分隔(可选) */ | |||||
| request.setTags("tag1,tag2"); | |||||
| /* 描述(可选) */ | |||||
| request.setDescription("test_desc"); | |||||
| /* 存储区域(可选) */ | |||||
| request.setStorageLocation("out-20170323225118266-5l3****wa.oss-cn-shanghai.aliyuncs.com"); | |||||
| /* 点播服务接入点 */ | |||||
| request.setApiRegionId(regionId); | |||||
| /* 设置应用ID*/ | |||||
| // request.setAppId("app-1000000"); | |||||
| // 开始上传 | |||||
| UploadAttachedMediaImpl uploader = new UploadAttachedMediaImpl(); | |||||
| UploadAttachedMediaResponse response = uploader.upload(request); | |||||
| System.out.print("RequestId=" + response.getRequestId() + "\n"); | |||||
| if (response.isSuccess()) { | |||||
| System.out.print("MediaId=" + response.getMediaId() + "\n"); | |||||
| System.out.print("MediaURL=" + response.getMediaURL() + "\n"); | |||||
| System.out.print("FileURL=" + response.getFileURL() + "\n"); | |||||
| } else { | |||||
| System.out.print("ErrorCode=" + response.getCode() + "\n"); | |||||
| System.out.print("ErrorMessage=" + response.getMessage() + "\n"); | |||||
| } | |||||
| } | |||||
| private static InputStream getFileStream(String fileName) { | |||||
| try { | |||||
| return new FileInputStream(fileName); | |||||
| } catch (FileNotFoundException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private static InputStream getUrlStream(String url) { | |||||
| try { | |||||
| return new URL(url).openStream(); | |||||
| } catch (IOException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public static String getUploadProgress(RedisTemplate<String, Object> redisTemplate,String videoId) { | |||||
| return UploadCacheHelper.getUploadProgress(redisTemplate, PutObjectProgressListener.PRE_VIDEO_PROGRESS+videoId); | |||||
| } | |||||
| } | |||||
| @@ -1,131 +0,0 @@ | |||||
| package com.iformall.video.aliyun.sdk.upload; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import com.aliyun.oss.event.ProgressEvent; | |||||
| import com.aliyun.oss.event.ProgressEventType; | |||||
| import com.aliyun.vod.upload.impl.VoDProgressListener; | |||||
| /** | |||||
| * 上传进度回调方法类 | |||||
| * 当您开启上传进度回调时该事件回调才会生效。 | |||||
| * OSS分片上传成功或失败均触发相应的回调事件,您可根据业务逻辑处理相应的事件回调。 | |||||
| * 当创建音视频信息成功后,此上传进度回调中的videoId为本次上传生成的视频ID,您可以根据视频ID进行音视频管理。 | |||||
| * 当创建图片信息成功后,此上传进度回调中的ImageId为本次上传生成的图片ID,您可以根据视频ID进行图片管理。 | |||||
| */ | |||||
| public class PutObjectProgressListener implements VoDProgressListener { | |||||
| /** | |||||
| * 已成功上传至OSS的字节数 | |||||
| */ | |||||
| private long bytesWritten = 0; | |||||
| /** | |||||
| * 原始文件的总字节数 | |||||
| */ | |||||
| private long totalBytes = -1; | |||||
| /** | |||||
| * 本次上传成功标记 | |||||
| */ | |||||
| private boolean succeed = false; | |||||
| /** | |||||
| * 视频ID | |||||
| */ | |||||
| private String videoId; | |||||
| /** | |||||
| * 图片ID | |||||
| */ | |||||
| private String imageId; | |||||
| public static final String PRE_VIDEO_PROGRESS = "video:progress:"; | |||||
| private RedisTemplate<String, Object> redisTemplate; | |||||
| public void progressChanged(ProgressEvent progressEvent) { | |||||
| long bytes = progressEvent.getBytes(); | |||||
| ProgressEventType eventType = progressEvent.getEventType(); | |||||
| switch (eventType) { | |||||
| // 开始上传事件 | |||||
| case TRANSFER_STARTED_EVENT: | |||||
| if (null != redisTemplate) { | |||||
| if (videoId != null) { | |||||
| UploadCacheHelper.cacheStart(redisTemplate, PRE_VIDEO_PROGRESS+videoId); | |||||
| //System.out.println("qqqqStart to upload videoId " + videoId + "......"); | |||||
| } | |||||
| if (imageId != null) { | |||||
| //System.out.println("aaaStart to upload imageId " + imageId + "......"); | |||||
| } | |||||
| } | |||||
| break; | |||||
| // 计算待上传文件总大小事件通知,只有调用本地文件方式上传时支持该事件 | |||||
| case REQUEST_CONTENT_LENGTH_EVENT: | |||||
| this.totalBytes = bytes; | |||||
| //System.out.println(this.totalBytes + "bytes in total will be uploaded to OSS."); | |||||
| break; | |||||
| // 已经上传成功文件大小事件通知 | |||||
| case REQUEST_BYTE_TRANSFER_EVENT: | |||||
| this.bytesWritten += bytes; | |||||
| if (this.totalBytes != -1) { | |||||
| int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes); | |||||
| //System.out.println(bytes + " bytes have been written at this time, upload progress: " + | |||||
| // percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")"); | |||||
| } else { | |||||
| //System.out.println(bytes + " bytes have been written at this time, upload sub total : " + | |||||
| // "(" + this.bytesWritten + ")"); | |||||
| } | |||||
| UploadCacheHelper.cacheProgress(redisTemplate, PRE_VIDEO_PROGRESS+videoId,String.valueOf(this.bytesWritten)); | |||||
| break; | |||||
| // 文件全部上传成功事件通知 | |||||
| case TRANSFER_COMPLETED_EVENT: | |||||
| this.succeed = true; | |||||
| if (videoId != null) { | |||||
| UploadCacheHelper.cacheComplete(redisTemplate, PRE_VIDEO_PROGRESS+videoId); | |||||
| //System.out.println("Succeed to upload videoId " + videoId + " , " + this.bytesWritten + " bytes have been transferred in total."); | |||||
| } | |||||
| if (imageId != null) { | |||||
| //System.out.println("Succeed to upload imageId " + imageId + " , " + this.bytesWritten + " bytes have been transferred in total."); | |||||
| } | |||||
| break; | |||||
| // 文件上传失败事件通知 | |||||
| case TRANSFER_FAILED_EVENT: | |||||
| if (videoId != null) { | |||||
| UploadCacheHelper.cacheProgress(redisTemplate, PRE_VIDEO_PROGRESS+videoId,String.valueOf(this.bytesWritten)); | |||||
| System.out.println("Failed to upload videoId " + videoId + " , " + this.bytesWritten + " bytes have been transferred."); | |||||
| } | |||||
| if (imageId != null) { | |||||
| //System.out.println("Failed to upload imageId " + imageId + " , " + this.bytesWritten + " bytes have been transferred."); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| public boolean isSucceed() { | |||||
| return succeed; | |||||
| } | |||||
| public void onVidReady(String videoId) { | |||||
| setVideoId(videoId); | |||||
| } | |||||
| public void onImageIdReady(String imageId) { | |||||
| setImageId(imageId); | |||||
| } | |||||
| public String getVideoId() { | |||||
| return videoId; | |||||
| } | |||||
| public void setVideoId(String videoId) { | |||||
| this.videoId = videoId; | |||||
| } | |||||
| public String getImageId() { | |||||
| return imageId; | |||||
| } | |||||
| public void setImageId(String imageId) { | |||||
| this.imageId = imageId; | |||||
| } | |||||
| } | |||||
| @@ -1,37 +0,0 @@ | |||||
| package com.iformall.video.aliyun.sdk.upload; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import org.springframework.data.redis.core.ValueOperations; | |||||
| public class UploadCacheHelper { | |||||
| public static void cacheStart(RedisTemplate<String, Object> template,String key) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(key, "begin", 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static void cacheComplete(RedisTemplate<String, Object> template,String key) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(key, "complete", 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static void cacheProgress(RedisTemplate<String, Object> template,String key,String bytes) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| operations.set(key, bytes, 24*3600,TimeUnit.SECONDS); | |||||
| } | |||||
| public static String getUploadProgress(RedisTemplate<String, Object> template,String key) { | |||||
| if (template.hasKey(key)) { | |||||
| ValueOperations<String, Object> operations = template.opsForValue(); | |||||
| Object o = operations.get(key); | |||||
| if (o instanceof String) { | |||||
| return (String)o; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,50 @@ | |||||
| package com.iformall.video.aliyun.thread; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.core.task.AsyncTaskExecutor; | |||||
| import org.springframework.scheduling.annotation.EnableAsync; | |||||
| import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | |||||
| import com.iformall.video.aliyun.config.AliyunVideoConfig; | |||||
| import lombok.Data; | |||||
| import java.util.concurrent.Executor; | |||||
| import java.util.concurrent.ThreadPoolExecutor; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| @Data | |||||
| @Configuration | |||||
| @EnableAsync | |||||
| @ConfigurationProperties(prefix = "video.aliyun") | |||||
| public class AliyunVedioThreadExecutorConfig { | |||||
| private int corePoolSize; | |||||
| private int maxPoolSize; | |||||
| private int queueCapacity; | |||||
| private String namePrefix; | |||||
| @Bean(name = "asyncVideoServiceExecutor") | |||||
| public Executor asyncVideoServiceExecutor() { | |||||
| ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); | |||||
| //配置核心线程数 | |||||
| executor.setCorePoolSize(corePoolSize); | |||||
| //配置最大线程数 | |||||
| executor.setMaxPoolSize(maxPoolSize); | |||||
| //配置队列大小 | |||||
| executor.setQueueCapacity(queueCapacity); | |||||
| //配置线程池中的线程的名称前缀 | |||||
| executor.setThreadNamePrefix(namePrefix); | |||||
| // rejection-policy:当pool已经达到max size的时候,如何处理新任务 | |||||
| // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 | |||||
| executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); | |||||
| //执行初始化 | |||||
| executor.initialize(); | |||||
| return executor; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,32 @@ | |||||
| package com.iformall.video.aliyun.thread; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse; | |||||
| import com.iformall.video.aliyun.sdk.server.AliyunVedioServer; | |||||
| import com.iformall.video.aliyun.sdk.server.UploadCacheHelper; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import java.io.InputStream; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | |||||
| import org.springframework.scheduling.annotation.Async; | |||||
| //https://blog.csdn.net/m0_37701381/article/details/81072774 | |||||
| @Service | |||||
| @Slf4j | |||||
| public class AliyunVideoUploadThread { | |||||
| @Async("asyncVideoServiceExecutor") | |||||
| public void executeAysncTask(CreateUploadVideoResponse response,String localFile,RedisTemplate<String, Object> redisTemplate) throws InterruptedException { | |||||
| try { | |||||
| AliyunVedioServer.uploadVideo(response, localFile,redisTemplate); | |||||
| } catch (UnsupportedEncodingException e) { | |||||
| log.error("AliyunVideoUploadThread upload error."+response.getVideoId(),e); | |||||
| UploadCacheHelper.cacheError(redisTemplate, response.getVideoId()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -156,11 +156,6 @@ | |||||
| <artifactId>rocketmq-spring-boot-starter</artifactId> | <artifactId>rocketmq-spring-boot-starter</artifactId> | ||||
| <version>1.0.0.RELEASE</version> | <version>1.0.0.RELEASE</version> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.apache.rocketmq</groupId> | |||||
| <artifactId>rocketmq-client</artifactId> | |||||
| <version>4.4.0</version> | |||||
| </dependency> | |||||
| <dependency> | <dependency> | ||||
| <groupId>org.apache.commons</groupId> | <groupId>org.apache.commons</groupId> | ||||