尚硅谷谷粒学院学习笔记7--阿里云视频点播+整合springcloud

阿里云视频点播

视频点播(ApsaraVideo for VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速于一体的一站式音视频点播解决方案。

在service下面新建service_vod模块

依赖

<dependencies>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-vod</artifactId>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-sdk-vod-upload</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>

application.properties

# 服务端口
server.port=8003
# 服务名
spring.application.name=service-vod

# 环境设置:dev、test、prod
spring.profiles.active=dev

#阿里云 vod
#不同的服务器,地址不同
aliyun.vod.file.keyid=
aliyun.vod.file.keysecret=

# 最大上传单个文件大小:默认1M
spring.servlet.multipart.max-file-size=1024MB
# 最大置总上传的数据大小 :默认10M
spring.servlet.multipart.max-request-size=1024MB

启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan(basePackages = {
    
    "com.atguigu"})
public class VodApplicaton {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(VodApplicaton.class,args);
    }
}

阿里云视频点播测试

初始化

import com.aliyun.oss.ClientException;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;

public class InitObject {
    
    
    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;
    }
}

获取视频播放地址

 public static void main(String[] args) throws ClientException {
    
    
        //根据视频id获取视频播放地址
        //创建初始化对象
        DefaultAcsClient client =InitObject.initVodClient("LTAI5tM89q3RBzKxsDh6b8", "rXd2Ze5DzS9C2izYF6ISoX9fI3I");
        GetPlayInfoResponse response = new GetPlayInfoResponse();
        GetPlayInfoRequest request=new GetPlayInfoRequest();
        //向request对象里面设置视频id
        request.setVideoId("e9aff412746a4868958bc4f5f4ba771e");
        //调用初始化对象里面的方法,传递request,获取数据
       response = client.getAcsResponse(request);
        List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
        //播放地址
        for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
    
    
            System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n");
        }
        //Base信息
        System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n");
    }

获取视频播放凭证

public static void main(String[] args) throws ClientException {
    
    
        //根据视频id获取视频播放地址
        //创建初始化对象
        DefaultAcsClient client =InitObject.initVodClient("LTAI5tM89q3RBzKxDh6b8", "rXd2Ze5DzS9C2izYF6ISoX9fI3I");

        //创建获取视频凭证request和response对象
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();
        //向request对象里面设置视频id
        request.setVideoId("e9aff412746a4868958bc4f5f4ba771e");
        //调用初始化对象里面的方法,传递request,获取凭证
        response = client.getAcsResponse(request);
        //播放凭证
        System.out.print("PlayAuth = " + response.getPlayAuth() + "\n");
        //VideoMeta信息
        System.out.print("VideoMeta.Title = " + response.getVideoMeta().getTitle() + "\n");

    }

安装非开源jar包

在这里插入图片描述
在本地Maven仓库中安装jar包:
下载视频上传SDK,解压,命令行进入lib目录,执行以下代码

mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.11 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.11.jar

然后在pom中引入jar包

<dependency>

    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-sdk-vod-upload</artifactId>
    <version>1.4.11</version>
</dependency>

测试本地文件上传

 public static void main(String[] args) {
    
    
        String accessKeyId = "LTAI4FvvVEWiTJ3GNJJqJnk7";
        String accessKeySecret = "9st82dv7EvFk9mTjYO1XXbM632fRbG";

        String title = "6 - What If I Want to Move Faster - upload by sdk";   //上传之后文件名称
        String fileName = "F:/6 - What If I Want to Move Faster.mp4";  //本地文件路径和名称
        //上传视频的方法
        UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName);
        /* 可指定分片上传时每个分片的大小,默认为2M字节 */
        request.setPartSize(2 * 1024 * 1024L);
        /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
        request.setTaskNum(1);

        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadVideoResponse response = uploader.uploadVideo(request);

        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");
        }
    }

整合阿里云vod实现视频上传

创建常量类

一定要注意注入容器不然后面返回的视频id一直会为空

@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_ID;
    public static String ACCESS_KEY_SECRET;

    @Override
    public void afterPropertiesSet() throws Exception {
    
    
        ACCESS_KEY_ID = keyId;
        ACCESS_KEY_SECRET = keySecret;
    }
}

创建service

public interface VodService {
    
    
    String uploadVideoAly(MultipartFile file);
}

VideoServiceImpl


package com.atguigu.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.atguigu.vod.service.VodService;
import com.atguigu.vod.utils.ConstantVodUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

@Service
public class VodServiceImpl implements VodService {
    
    
    @Override
    public String uploadVideoAly(MultipartFile file) {
    
    
        try {
    
    
            //accessKeyId, accessKeySecret
            //fileName:上传文件原始名称
            // 01.03.09.mp4
            String fileName = file.getOriginalFilename();
            //title:上传之后显示名称
            String title = fileName.substring(0, fileName.lastIndexOf("."));
            //inputStream:上传文件输入流
            InputStream inputStream = file.getInputStream();
            UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.ACCESS_KEY_ID,ConstantVodUtils.ACCESS_KEY_SECRET, title, fileName, inputStream);

            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);

            String videoId = null;
            if (response.isSuccess()) {
    
    
                videoId = response.getVideoId();
            } else {
    
     //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
                videoId = response.getVideoId();
            }
            return videoId;
        }catch(Exception e) {
    
    
            e.printStackTrace();
            
            return null;
        }
    }
}


创建controller

@RestController
@RequestMapping("/eduvod/video")
@CrossOrigin
public class VodController {
    
    
    @Autowired
    private VodService vodService;

    @PostMapping("uploadAlyiVideo")
    public ResultVo uploadAlyiVideo(MultipartFile file){
    
    
//        返回上传视频id
       String videoId= vodService.uploadVideoAly(file);
        return ResultVo.ok().data("videoId",videoId);
    }

    //上传视频到阿里云

}

整合视频前端

配置nginx反向代理

location ~ /eduvod/ {
    
    
            proxy_pass http://localhost:8003;
        }

配置nginx上传文件大小,否则上传时会有 413 (Request Entity Too Large) 异常
打开nginx主配置文件nginx.conf,找到http{},添加

client_max_body_size 1024m;

在这里插入图片描述

重启nginx

nginx -s reload

数据定义

 fileList: [], //上传文件列表
 BASE_API: process.env.BASE_API, // 接口API地址

整合上传组件

<el-form-item label="上传视频">
          <el-upload
            :on-success="handleVodUploadSuccess"
            :on-remove="handleVodRemove"
            :before-remove="beforeVodRemove"
            :on-exceed="handleUploadExceed"
            :file-list="fileList"
            :action="BASE_API + '/eduvod/video/uploadAlyiVideo'"
            :limit="1"
            class="upload-demo"
          >
            <el-button size="small" type="primary">上传视频</el-button>
            <el-tooltip placement="right-end">
              <div slot="content">
                最大支持1G,<br />
                支持3GP、ASF、AVI、DAT、DV、FLV、F4V、<br />
                GIF、M2T、M4V、MJ2、MJPEG、MKV、MOV、MP4、<br />
                MPE、MPG、MPEG、MTS、OGG、QT、RM、RMVB、<br />
                SWF、TS、VOB、WMV、WEBM 等视频格式上传
              </div>
              <i class="el-icon-question" />
            </el-tooltip>
          </el-upload>
        </el-form-item>
      </el-form>

方法定义

//上传视频成功调用的方法
    handleVodUploadSuccess(response, file, fileList) {
    
    
      //上传视频id赋值
      this.video.videoSourceId = response.data.videoId;
      //上传视频名称赋值
      this.video.videoOriginalName = file.name;
    },
    handleUploadExceed() {
    
    
      this.$message.warning("想要重新上传视频,请先删除已上传的视频");
    },

删除云端视频

后端

controller

@DeleteMapping("removeAlyVideo/{id}")
    public ResultVo removeAlyVideo(@PathVariable String id){
    
    
       try {
    
    
           //初始化对象
           DefaultAcsClient client = InitVodClient.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);
           //创建删除视频的request对象
           DeleteVideoRequest request=new DeleteVideoRequest();
           //向request设置删除的视频id
           request.setVideoIds(id);
           client.getAcsResponse(request);
           return ResultVo.ok();
       }catch (Exception e){
    
    
            e.printStackTrace();
            throw new GuliException(20001,"删除视频失败");
       }

   }

前端

定义api

//删除视频
  deleteAliyunvod(id) {
    
    
    return request({
    
    
      url: '/eduvod/video/removeAlyVideo/' + id,
      method: 'delete'
    })
  }

组件方法

//点击确定调用的方法
    handleVodRemove() {
    
    
      //调用接口的删除视频的方法
      video.deleteAliyunvod(this.video.videoSourceId).then((response) => {
    
    
        //提示信息
        this.$message({
    
    
          type: "success",
          message: "删除视频成功!",
        });
        //把文件列表清空
        this.fileList = [];
        //把video视频id和视频名称值清空
        //上传视频id赋值
        this.video.videoSourceId = "";
        //上传视频名称赋值
        this.video.videoOriginalName = "";
      });
    },
    //点击×调用这个方法
    beforeVodRemove(file, fileList) {
    
    
      return this.$confirm(`确定移除 ${
    
    file.name}?`);
    },

springcloud&&springcloudalibaba

springcloud笔记链接
springcloudalibaba笔记链接

服务注册

把service-edu微服务注册到注册中心中,service-vod步骤相同

在service模块配置pom

原先依赖是注释掉的打开即可

		<dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

添加服务配置信息

配置application.properties,在客户端微服务中添加注册Nacos服务的配置信息

扫描二维码关注公众号,回复: 13281091 查看本文章
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

添加Nacos客户端注解

在客户端微服务启动类中添加注解

@EnableDiscoveryClient

实现服务调用

删除课时的同时删除云端视频

在service模块添加pom依赖

<!--服务调用-->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-openfeign</artifactId>
         </dependency>

在调用端的启动类添加注解

@EnableFeignClients
@SpringBootApplication
@ComponentScan(basePackages = {
    
    "com.atguigu"})
@EnableDiscoveryClient
@EnableFeignClients
public class EduApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(EduApplication.class,args);
    }
}

创建包和接口

创建feignclient包
@FeignClient注解用于指定从哪个服务中调用功能 ,名称与被调用的服务名保持一致。
@GetMapping注解用于对被调用的微服务进行地址映射。
@PathVariable注解一定要指定参数名称,否则出错
@Component注解防止,在其他位置注入CodClient时idea报错

@FeignClient("service-vod")
@Component
public interface VodClient {
    
    
    @DeleteMapping("/eduvod/video/removeAlyVideo/{id}")
    public ResultVo removeAlyVideo(@PathVariable("id") String id);
}

注入

@Autowired 
private VodClient vodClient;

调用微服务

@PostMapping("{id}")
    @ApiOperation(value = "根据ID删除课时")
    @ApiParam(name = "id", value = "课时ID", required = true)
    public ResultVo deleteVideo(@PathVariable String id){
    
    
         //根据小节id获取视频id,调用方法实现视频删除
        EduVideo eduVideo = videoService.getById(id);
        String videoSourceId = eduVideo.getVideoSourceId();
        //判断小节里面是否有视频id
        if(!StringUtils.isEmpty(videoSourceId)){
    
    
            vodClient.removeAlyVideo(videoSourceId);
        }

        boolean b = videoService.removeById(id);
        if(b){
    
    
            return ResultVo.ok();
        }
        else{
    
    
            return ResultVo.error();
        }
    }

完善删除课程业务

删除课程的同时删除云端视频

VideoService

void removeMoreAlyVideo(List videoIdList);

VideoServiceImpl

@Override
    public void removeMoreAlyVideo(List videoIdList) {
    
    
        try {
    
    
            //初始化对象
            DefaultAcsClient client = InitVodClient.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);
            //创建删除视频的request对象
            DeleteVideoRequest request=new DeleteVideoRequest();
            //向request设置删除的视频id
            String ids = StringUtils.join(videoIdList.toArray(), ",");
            request.setVideoIds(ids);
            client.getAcsResponse(request);

        }catch (Exception e){
    
    
            e.printStackTrace();
            throw new GuliException(20001,"删除视频失败");
        }
    }

controller

//删除多个阿里云视频的方法
    //参数多个视频id list
    @DeleteMapping("delete-batch")
    public ResultVo deleteBatch(@RequestParam("videoIdList") List<String> videoIdList){
    
    
        vodService.removeMoreAlyVideo(videoIdList);
        return ResultVo.ok();
    }

VodClient.

@DeleteMapping("/eduvod/video/delete-batch")
    public ResultVo deleteBatch(@RequestParam("videoIdList") List<String> videoIdList);

EduVideoServiceImpl

@Autowired
    private VodClient vodClient;
    @Override
    public void removeVideoByCourseId(String courseId) {
    
    
        //根据课程id查询所有视频id
        QueryWrapper<EduVideo> Wrapper = new QueryWrapper<>();
        Wrapper.eq("course_id",courseId);
        Wrapper.select("video_source_id");
        List<EduVideo> videoList = baseMapper.selectList(Wrapper);
        //List<EduVideo>变成List<string>
        List<String> videoIds=new ArrayList<>();
        for (int i = 0; i < videoList.size(); i++) {
    
    
            EduVideo eduVideo = videoList.get(i);
            if(!StringUtils.isEmpty(eduVideo)){
    
    
                String videoSourceId = eduVideo.getVideoSourceId();
                videoIds.add(videoSourceId);
            }


        }
        if(videoIds.size()>0){
    
    
            vodClient.deleteBatch(videoIds);
        }

        QueryWrapper<EduVideo> QueryWrapper = new QueryWrapper<>();
        QueryWrapper.eq("course_id",courseId);
        baseMapper.delete(QueryWrapper);
    }

EduCourseServiceImpl

@Override
    public boolean removeCourse(String courseId) {
    
    

        //根据课程id删除小节
        eduVideoService.removeVideoByCourseId(courseId);
        //根据课程id删除章节
        chapterService.removeChapterByCourseId(courseId);
        //根据课程id删除描述
        courseDescriptionService.removeById(courseId);
        //根据课程id删除课程本身
        int i = baseMapper.deleteById(courseId);
        if(i==0){
    
    
            throw new GuliException(20001,"删除失败");
        }
        return true;
    }

整合Hystrix

在service的pom中添加依赖

 <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
           </dependency>

        <!--hystrix依赖,主要是用  @HystrixCommand -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <!--服务注册-->
        <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
         </dependency>
        <!--服务调用-->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-openfeign</artifactId>
         </dependency>

在配置文件中添加hystrix配置

#开启熔断机制
feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
feign:
  hystrix:
    enabled: true

设置超时时间yml好像没有提示

在service-edu的client包里面创建熔断器的实现类

@Component
public class VodFileDegradeFeignClient implements VodClient{
    
    
    @Override
    public ResultVo removeAlyVideo(String id) {
    
    
        return ResultVo.error().message("删除视频出错了");
    }

    @Override
    public ResultVo deleteBatch(List<String> videoIdList) {
    
    
        return ResultVo.error().message("删除多个视频出错了");
    }
}

修改VodClient接口的注解

@FeignClient(name="service-vod",fallback = VodFileDegradeFeignClient.class)

public interface VodClient {
    
    
    @DeleteMapping("/eduvod/video/removeAlyVideo/{id}")
    public ResultVo removeAlyVideo(@PathVariable("id") String id);

    @DeleteMapping("/eduvod/video/delete-batch")
    public ResultVo deleteBatch(@RequestParam("videoIdList") List<String> videoIdList);
}

测试熔断

//删除小节

    @PostMapping("{id}")
    @ApiOperation(value = "根据ID删除课时")
    @ApiParam(name = "id", value = "课时ID", required = true)
    public ResultVo deleteVideo(@PathVariable String id){
    
    
         //根据小节id获取视频id,调用方法实现视频删除
        EduVideo eduVideo = videoService.getById(id);
        String videoSourceId = eduVideo.getVideoSourceId();
        //判断小节里面是否有视频id
        if(!StringUtils.isEmpty(videoSourceId)){
    
    
            ResultVo result = vodClient.removeAlyVideo(videoSourceId);
            if (result.getCode()==20001){
    
    
                throw new GuliException(20001,"删除视频失败,熔断器...");
            }
        }

        boolean b = videoService.removeById(id);
        if(b){
    
    
            return ResultVo.ok();
        }
        else{
    
    
            return ResultVo.error();
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_44866153/article/details/120606205