阿里云视频点播资源迁移及回溯校验

一:准备环境

1.1、搭建springboot

建一个Springboot项目。
需要做的就是 配置一个datasource,加一个mybatis-plus即可。
网上教程很多,不多说了。

1.2、引入外部包

如图,将资源包全部添加即可。资源在文末。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二:表与配置

2.1、拉取视频点播文件

登录阿里云视频点播平台
在这里插入图片描述
按照需要的内容导出即可
在这里插入图片描述
注意:有可能出现导出之后下载不了的情况,这个事情就需要在阿里云提工单,从后台导出,会更快一些。

导出的是 .csv文件,和Excel一样的打开方式,类似下面这种文件内容。
在这里插入图片描述

2.2、建表

创建表 t_video

CREATE TABLE `t_video` (
  `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `MEDIA_ID` varchar(100) DEFAULT NULL COMMENT '媒体ID',
  `MEDIA_NAME` varchar(100) DEFAULT NULL COMMENT '媒体名称',
  `MEDIA_DURATION` varchar(100) DEFAULT NULL COMMENT '媒体时长(s)',
  `MEDIA_SIZE` varchar(100) DEFAULT NULL COMMENT '媒体大小(bytes)',
  `TYPE` varchar(100) DEFAULT NULL COMMENT '分类',
  `TYPE_CODE` varchar(100) DEFAULT NULL COMMENT '分类CODE',
  `MEDIA_CREATE_TIME` varchar(100) DEFAULT NULL COMMENT '创建时间',
  `MEDIA_UPDATE_TIME` varchar(100) DEFAULT NULL COMMENT '最新更新',
  `MEDIA_SOURCE_PATH` varchar(2000) DEFAULT NULL COMMENT '源文件地址',
  `MEDIA_MP4_PATH` varchar(2000) DEFAULT NULL COMMENT '源文件地址MP4',
  `MEDIA_STANDARD_PATH` varchar(2000) DEFAULT NULL COMMENT '标清_M3U8',
  `MEDIA_SOURCE_MP4_PATH` varchar(2000) DEFAULT NULL COMMENT '原画_MP4',
  `MEDIA_STANDARD_MP4_PATH` varchar(2000) DEFAULT NULL COMMENT '标清_MP4',
  `CREATE_TIME` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `UPDATE_TIME` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `STATUS` char(1) DEFAULT '0' COMMENT '状态:0-未同步,1-已同步,2-数据异常,3-视频无法访问,4-无视频',
  `SUCCESS` varchar(50) DEFAULT '0' COMMENT '校验视频 0:未校验;1:无视频;有视频则保存视频状态',
  PRIMARY KEY (`ID`),
  KEY `NK_MEDIA_CREATE_TIME` (`MEDIA_CREATE_TIME`) USING BTREE,
  KEY `NK_STATUS` (`STATUS`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频同步表';

重要字段说明:
MEDIA_NAME:就是上传视频的唯一标识,依据该标识可以找到对应的视频信息。
TYPE:迁移之后,新的环境对应的视频分类是不一样的,所以需要做一下映射。
MEDIA_MP4_PATH:视频的访问地址,可以用该地址访问视频内容。
STATUS:用来记录视频迁移状态的字段,0-未同步,1-已同步,2-数据异常,3-视频无法访问,4-无视频
SUCCESS:用来做视频回溯校验的字段,校验视频 0:未校验;1:无视频;有视频则保存视频状态

2.3、yml配置文件

server:
  port: 8008
  servlet:
    context-path: /export

spring:
  mvc:
    view:
      suffix: .html

  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB

# 数据源配置
  datasource:
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/video?characterEncoding=utf8&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    min: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: config,stat,wall
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

# 使用mybatis-plus
mybatis-plus:
  mapper-locations:
  - classpath*:/mybatis/mapper/*.xml

  type-aliases-package: com.export.entity;
  global-config:
    id-type: 3
    db-column-underline: true
    field-strategy: 2

  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false
    call-setters-on-nulls: true

logging:
  file: /log/generate.log
  level:
    com.cpic.chjb: INFO
  root: INFO

info:
  app:
    name: test

三:代码

3.1、XML

VideoBaseMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.export.VideoBaseMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.export.VideoEntity">
        <id column="ID" property="id" />
        <result column="MEDIA_ID" property="mediaId" />
        <result column="MEDIA_NAME" property="mediaName" />
        <result column="MEDIA_DURATION" property="mediaDuration" />
        <result column="MEDIA_SIZE" property="mediaSize" />
        <result column="TYPE" property="type" />
        <result column="TYPE_CODE" property="typeCode" />
        <result column="MEDIA_CREATE_TIME" property="mediaCreateTime" />
        <result column="MEDIA_UPDATE_TIME" property="mediaUpdateTime" />
        <result column="MEDIA_SOURCE_PATH" property="mediaSourcePath" />
        <result column="MEDIA_MP4_PATH" property="mediaMp4Path" />
        <result column="MEDIA_STANDARD_PATH" property="mediaStandardPath" />
        <result column="MEDIA_SOURCE_MP4_PATH" property="mediaSourceMp4Path" />
        <result column="MEDIA_STANDARD_MP4_PATH" property="mediaStandardMp4Path" />
        <result column="CREATE_TIME" property="createTime" />
        <result column="UPDATE_TIME" property="updateTime" />
        <result column="STATUS" property="status" />
        <result column="SUCCESS" property="success" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        ID, MEDIA_ID, MEDIA_NAME, MEDIA_DURATION, MEDIA_SIZE, TYPE, TYPE_CODE, MEDIA_CREATE_TIME, MEDIA_UPDATE_TIME, MEDIA_SOURCE_PATH, MEDIA_MP4_PATH, MEDIA_STANDARD_PATH, MEDIA_SOURCE_MP4_PATH, MEDIA_STANDARD_MP4_PATH, CREATE_TIME, UPDATE_TIME, STATUS, SUCCESS
    </sql>

</mapper>

3.2、entity

VideoEntity.java

package com.export;

import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("T_VIDEO")
public class VideoEntity extends Model<VideoEntity> {
    
    
    private static final long serialVersionUID = 1L;
    /**
     * 自增列
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    //媒体ID
    private String mediaId;
    //媒体名称
    private String mediaName;
    //媒体时长(s)
    private String mediaDuration;
    //媒体大小(bytes)
    private String mediaSize;
    //分类
    private String type;
    //分类CODE
    private String typeCode;
    //创建时间
    private String mediaCreateTime;
    //最新更新
    private String mediaUpdateTime;
    //源文件地址
    private String mediaSourcePath;
    //源文件地址MP4
    private String mediaMp4Path;
    //标清_M3U8
    private String mediaStandardPath;
    //原画_MP4
    private String mediaSourceMp4Path;
    //标清_MP4
    private String mediaStandardMp4Path;
    //创建时间
    private Date createTime;
    //更新时间
    private Date updateTime;
    //状态:0-未同步,1-已同步,2-数据异常,3-视频无法访问,4-无视频
    private String status;
    //校验视频 0:未校验;1:无视频;有视频则保存视频状态
    private String success;

    @Override
    protected Serializable pkVal() {
    
    
        return this.id;
    }
}

3.3、mapper

VideoBaseMapper.java

package com.export;

import com.baomidou.mybatisplus.mapper.BaseMapper;

public interface VideoBaseMapper extends BaseMapper<VideoEntity> {
    
    

}

3.4、Synchronize

package com.export;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 使用上传SDK进行视频文件上传
 */
@Slf4j
public class VideoSynchronize {
    
    

    public final static String KEY_ID = "**********";
    public final static String KEY_SECRET = "**********";
    //视频类别映射,由原视频类型,映射成新环境视频类型
    public static final Map<String,String> map = new HashMap<>();
    static {
    
    
        map.put("11111","22222");
    }

    /**
     * 流式上传接口
     * @param accessKeyId KEY_ID
     * @param accessKeySecret KEY_SECRET
     * @param title 媒体名称
     * @param fileName 文件名称
     * @param inputStream 流
     * @param cateId 文件类别
     */
    private static void uploadStream(String accessKeyId, String accessKeySecret, String title,
                                         String fileName, InputStream inputStream, Long cateId) throws RuntimeException{
    
    
        UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream);
        /* 自定义消息回调设置,参数说明请参见基本数据类型 */
        //request.setUserData(""{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://example.aliyundoc.com\"}}"");
        /* 视频分类ID(可选) */
        request.setCateId(cateId);
        /* 视频标签,多个用逗号分隔(可选) */
        //request.setTags("标签1,标签2");
        /* 视频描述(可选) */
        //request.setDescription("视频描述");
        /* 封面图片(可选) ,如http://****.example.com/image_01.jpg*/
        //request.setCoverURL("<Your CoverURL>");
        /* 模板组ID(可选) */
        //request.setTemplateGroupId("8c4792cbc8694e****fd5330e56a33d");
        /* 工作流ID(可选) */
        //request.setWorkflowId("d4430d07361f****1339577859b0177b");
        /* 存储区域(可选) */
        //request.setStorageLocation("outin-20170323****266-5sejdln9o.oss-cn-shanghai.aliyuncs.com");
        /* 点播服务接入点 */
        request.setApiRegionId("cn-shanghai");
        /* ECS部署区域*/
        // request.setEcsRegionId("cn-shanghai");
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadStreamResponse response = uploader.uploadStream(request);
        log.info("RequestId=" + response.getRequestId() + "\n");  //请求视频点播服务的请求ID
        if (response.isSuccess()) {
    
    
            log.info("VideoId=" + response.getVideoId() + "\n");
        } else {
    
     //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
            log.info("VideoId=" + response.getVideoId() + "\n");
            log.info("ErrorCode=" + response.getCode() + "\n");
            log.info("ErrorMessage=" + response.getMessage() + "\n");
            throw new RuntimeException();
        }
    }

    public static void synchronizeData(VideoEntity videoBean) throws IOException {
    
    
        /*//用户可自行添加url数据源,并传入视频媒资信息,上传视频资源
        InputStream inputStream = null;
        //您的视频地址。如http://example.aliyundoc.com/video*/
        String url = videoBean.getMediaMp4Path();
        InputStream inputStream = new URL(url).openStream();
        //以下参数重的AccessKey ID, AccessKey Secret提前准备好的AccessKey信息。<Your Video Title>为视频标题。<Your Video with File Extension>为含文件扩展名的视频,如video-1.mp4。
        uploadStream(KEY_ID, KEY_SECRET, videoBean.getMediaName(), videoBean.getMediaId() + ".MP4",
                inputStream, Long.valueOf(map.get(videoBean.getTypeCode())));
    }

}

3.5、视频迁移Controller

package com.export;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Controller
public class VideoController extends ServiceImpl<VideoBaseMapper, VideoEntity>{
    
    

    private final static String VIDEO_STATUS_0 = "0";//未同步
    private final static String VIDEO_STATUS_1 = "1";//已同步
    private final static String VIDEO_STATUS_2 = "2";//数据异常
    private final static String VIDEO_STATUS_3 = "3";//视频无法访问
    private final static String VIDEO_STATUS_4 = "4";//无视频

    // http://localhost:8008/export/video
    @RequestMapping("/video")
    @ResponseBody
    public void queryDictionaryAllList(HttpServletResponse response) throws Exception {
    
    
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Catch-Control","no-cache");
        //1、查询数据库没有执行数据
        EntityWrapper<VideoEntity> wrapper = new EntityWrapper<>();
        wrapper.in("STATUS", Collections.singletonList(VIDEO_STATUS_0));
        wrapper.orderBy("ID", true);
        wrapper.isNotNull("MEDIA_MP4_PATH");
        wrapper.last("limit 1000");
        List<VideoEntity> videoEntityList = baseMapper.selectList(wrapper);
        if(null == videoEntityList || videoEntityList.size() == 0) return;
        //2、设置一个值放置别的线程拉取到这部分数据
        for (VideoEntity video : videoEntityList) {
    
    
            video.setStatus("a");
        }
        updateBatchById(videoEntityList);
        //3、开启一个异步线程跑数据
        Date now = new Date();
        Thread thread = new Thread(() ->{
    
    
            for(VideoEntity videoEntity : videoEntityList){
    
    
                VideoEntity videoCheck = baseMapper.selectById(videoEntity.getId());
                if(null == videoCheck || VIDEO_STATUS_1.equals(videoCheck.getStatus())){
    
    
                    continue;
                }
                //单独校验一次文件流是否存在
                try {
    
    
                    InputStream inputStream = new URL(videoEntity.getMediaMp4Path()).openStream();
                } catch (Exception e){
    
    
                    videoEntity.setStatus(VIDEO_STATUS_3);
                    videoEntity.setUpdateTime(now);
                    baseMapper.updateById(videoEntity);
                    continue;
                }
                //同步视频
                try {
    
    
                    VideoSynchronize.synchronizeData(videoEntity);
                    videoEntity.setStatus(VIDEO_STATUS_1);
                } catch (Exception e){
    
    
                    log.error("Current Thread Write Excel Error", e);
                    videoEntity.setStatus(VIDEO_STATUS_2);
                } finally {
    
    
                    videoEntity.setUpdateTime(now);
                    baseMapper.updateById(videoEntity);
                }
            }
//        writeDataPool(videoEntityList);
        });
        thread.start();
    }

    //线程池(在使用线程池多线程跑视频迁移的过程中,发现存在大量迁移失败的情况,猜测应该是做了限流之类的东西)
    private void writeDataPool(List<VideoEntity> list) {
    
    
        Integer poolSize = 1000;
        ExecutorService pool = new ThreadPoolExecutor(poolSize, 2 * poolSize, poolSize, TimeUnit.MILLISECONDS,
        new ArrayBlockingQueue<Runnable>(1), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        for (VideoEntity video : list) {
    
    
            pool.execute(new writeDataThread(video));
        }
        try {
    
    
            pool.shutdown();
            boolean loop = true;
            do {
    
    
                loop = !pool.awaitTermination(200, TimeUnit.MILLISECONDS);
            } while (loop);
        } catch (InterruptedException e) {
    
    
            log.error("Current Thread Pool Error", e);
        }
    }

    private class writeDataThread implements Runnable {
    
    
        private VideoEntity videoEntity;
        public writeDataThread(VideoEntity videoEntity) {
    
    
            this.videoEntity = videoEntity;
        }
        @Override
        public void run() {
    
    
            try {
    
    
                VideoSynchronize.synchronizeData(videoEntity);
                videoEntity.setStatus(VIDEO_STATUS_1);
            } catch (Exception e){
    
    
                log.error("Current Thread Write Excel Error", e);
                videoEntity.setStatus(VIDEO_STATUS_2);
            } finally {
    
    
                videoEntity.setUpdateTime(new Date());
                baseMapper.updateById(videoEntity);
            }
        }
    }

}

3.6、视频回溯校验Controller

package com.export;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.SearchMediaRequest;
import com.aliyuncs.vod.model.v20170321.SearchMediaResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Controller
public class CheckController extends ServiceImpl<VideoBaseMapper, VideoEntity> {
    
    

    private final static String VIDEO_SUCCESS_0 = "0";//未校验
    private final static String VIDEO_SUCCESS_1 = "1";//无视频
    private final static String VIDEO_SUCCESS_EXCEPTION = "Exception";//异常

    /**
     * 根据分类和视频名称查询视频
     */
    @RequestMapping("/check")
    @ResponseBody
    public void queryVideoByCate() throws Exception {
    
    
        //1、查询数据库未校验的视频,以及校验异常的视频
        EntityWrapper<VideoEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("STATUS", "1");
        wrapper.eq("SUCCESS", VIDEO_SUCCESS_0);
//        wrapper.eq("SUCCESS", VIDEO_SUCCESS_EXCEPTION);
        List<VideoEntity> videoEntityList = baseMapper.selectList(wrapper);
        if (null == videoEntityList || videoEntityList.size() == 0) return;
        Date now = new Date();
        Thread thread = new Thread(() ->{
    
    
            for (VideoEntity videoEntity : videoEntityList) {
    
    
                try {
    
    
                    List<VideoResponseDTO> list = checkVideo(videoEntity);
                    if (null != list) {
    
    
                        VideoResponseDTO videoResponseDTO = list.get(0);
                        videoEntity.setSuccess(videoResponseDTO.getStatus());
                    } else {
    
    
                        videoEntity.setSuccess(VIDEO_SUCCESS_1);//无视频
                    }
                } catch (Exception e) {
    
    
                    videoEntity.setSuccess(VIDEO_SUCCESS_EXCEPTION);//有异常
                } finally {
    
    
                    videoEntity.setUpdateTime(now);
                }
                baseMapper.updateById(videoEntity);
            }
        });
        thread.start();
    }

    private List<VideoResponseDTO> checkVideo(VideoEntity videoEntity) throws Exception {
    
    
        List<VideoResponseDTO> list = new ArrayList<>();
        // 拼接match条件(cateId)
        String matchCondition = "Status in ('UploadSucc','Transcoding','Checking','Blocked','Normal')";
        //查询cateId
        String cateId = VideoSynchronize.map.get(videoEntity.getTypeCode());
        matchCondition = matchCondition + " And CateId = " + cateId;
        VideoResponseDTO videoResponseDTO;
        if (null != videoEntity.getMediaName()) {
    
    
            matchCondition = matchCondition + " And Title = '" + videoEntity.getMediaName() + "'";
            // 查询对应分类下所有视频
            SearchMediaResponse videos = getVideos(matchCondition);
            for (SearchMediaResponse.Media media : videos.getMediaList()) {
    
    
                videoResponseDTO = new VideoResponseDTO();
                SearchMediaResponse.Media.Video videoInfo = media.getVideo();
                if (null != videoInfo.getVideoId()) {
    
    
                    videoResponseDTO.setVideoId(videoInfo.getVideoId());
                    videoResponseDTO.setCoverURL(videoInfo.getCoverURL());
                    videoResponseDTO.setStatus(videoInfo.getStatus());
                    // 时间转化
                    if (null != videoInfo.getDuration()) {
    
    
                        String s = String.valueOf(videoInfo.getDuration());
                        videoResponseDTO.setDuration(getDate(Integer.parseInt(s.substring(0, s.indexOf(".")))));
                    }
                }
                SearchMediaResponse.Media.Audio audio = media.getAudio();
                if (null != audio.getAudioId()) {
    
    
                    videoResponseDTO.setVideoId(audio.getAudioId());
                    videoResponseDTO.setCoverURL(audio.getCoverURL());
                    videoResponseDTO.setStatus(audio.getStatus());
                    // 时间转化
                    if (null != audio.getDuration()) {
    
    
                        String s = String.valueOf(audio.getDuration());
                        videoResponseDTO.setDuration(getDate(Integer.parseInt(s.substring(0, s.indexOf(".")))));
                    }
                }
                list.add(videoResponseDTO);
            }
        }
        return list;
    }

    /**
     * 获取视频信息
     */
    public SearchMediaResponse getVideos(String matchCondition) throws Exception {
    
    
        DefaultAcsClient client = initVodClient();
        SearchMediaRequest request = new SearchMediaRequest();
        request.setFields("Title,CoverURL,Status,CreationTime,ModificationTime,VideoId,Duration");
        request.setMatch(matchCondition);
        request.setSearchType("video");
        request.setSortBy("CreationTime:Asc");
        return searchMedia(client, request);
    }

    public static DefaultAcsClient initVodClient() throws IOException {
    
    
        String regionId = "cn-shanghai";  // 点播服务接入区域
        DefaultProfile profile;
        profile = DefaultProfile.getProfile(regionId, VideoSynchronize.KEY_ID, VideoSynchronize.KEY_SECRET);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }

    /*查找视频*/
    public static SearchMediaResponse searchMedia(DefaultAcsClient client, SearchMediaRequest request) throws Exception {
    
    
        return client.getAcsResponse(request);
    }

    /**
     * 秒转化为时分秒
     */
    public static String getDate(Integer date) {
    
    
        if (date < 60) {
    
    
            if (date < 10){
    
    
                return "00:0" + date;
            } else {
    
    
                return "00:" + date;
            }
        } else if (date > 60 && date < 3600) {
    
    
            String mm;
            String ss;
            int m = date/60;
            int s = date%60;
            if (m < 10){
    
    
                mm = "0" + m;
            } else {
    
    
                mm = String.valueOf(m);
            }
            if (s < 10){
    
    
                ss = "0" + s;
            } else {
    
    
                ss = String.valueOf(s);
            }
            return mm + ":" + ss;
        } else {
    
    
            String hh;
            String mm;
            String ss;
            int h = date/3600;
            int m = (date%3600)/60;
            int s = (date%3600)%60;
            if (m < 10){
    
    
                mm = "0" + m;
            } else {
    
    
                mm = String.valueOf(m);
            }
            if(s < 10){
    
    
                ss = "0" + s;
            } else {
    
    
                ss = String.valueOf(s);
            }
            if(h < 10){
    
    
                hh = "0" + h;
            } else {
    
    
                hh = String.valueOf(h);
            }
            return hh + ":" + mm + ":" + ss;
        }
    }

    public class VideoResponseDTO{
    
    
        //视频封面URL。
        private String coverURL;
        //视频创建时间。使用UTC时间。
        private String creationTime;
        //视频状态
        private String status;
        //视频分类名称
        private String cateName;
        //视频ID
        private String videoId;
        //视频标题
        private String title;
        //持续时间
        private String duration;
        public String getCoverURL() {
    
    
            return coverURL;
        }
        public void setCoverURL(String coverURL) {
    
    
            this.coverURL = coverURL;
        }
        public String getCreationTime() {
    
    
            return creationTime;
        }
        public void setCreationTime(String creationTime) {
    
    
            this.creationTime = creationTime;
        }
        public String getStatus() {
    
    
            return status;
        }
        public void setStatus(String status) {
    
    
            this.status = status;
        }
        public String getCateName() {
    
    
            return cateName;
        }
        public void setCateName(String cateName) {
    
    
            this.cateName = cateName;
        }
        public String getVideoId() {
    
    
            return videoId;
        }
        public void setVideoId(String videoId) {
    
    
            this.videoId = videoId;
        }
        public String getTitle() {
    
    
            return title;
        }
        public void setTitle(String title) {
    
    
            this.title = title;
        }
        public String getDuration() {
    
    
            return duration;
        }
        public void setDuration(String duration) {
    
    
            this.duration = duration;
        }
    }

}

四:资源

4.1、源码链接

CSDN资源链接:https://download.csdn.net/download/qq_38254635/87353068
百度网盘资源链接:https://pan.baidu.com/s/1fcPqK449h6NYzC-ADvMZMQ?pwd=54rp
提取码: 54rp

有什么不对的还望指正,书写不易,觉得有帮助就点个赞吧!

猜你喜欢

转载自blog.csdn.net/qq_38254635/article/details/128122779