草庐IT

谷粒学院 —— 10、课程管理:整合阿里云视频点播

Mr_zhangyj 2023-04-21 原文

目录

1、创建模块

1.1、引入视频点播所需依赖

1.2、application.properties

1.3、启动类

2、实现视频上传

2.1、后端

2.1.1、创建常量类

2.1.2、上传视频到阿里云

2.2、配置 nginx

2.3、前端

2.3.1、上传视频组件

2.3.2、方法定义

3、视频删除

3.1、后端

3.1.1、初始化阿里云视频点播客户端

3.1.2、根据视频 ID 删除阿里云视频

3.2、前端

3.2.1、定义 API

3.2.2、定义组件方法


1、创建模块

在 service 下创建 service_vod 模块

1.1、引入视频点播所需依赖

    <dependencies>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-vod</artifactId>
            <version>2.16.11</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-kms</artifactId>
            <version>2.10.1</version>
        </dependency>

        <!-- 视频上传 -->
        <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.16.11</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</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-sdk-vod-upload</artifactId>
            <version>1.4.15</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>

1.2、application.properties

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

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

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

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

1.3、启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) // 不加载数据库
@ComponentScan(basePackages = {"com.zyj"})  // 扫描包
public class VodApplication {
    public static void main(String[] args) {
        SpringApplication.run(VodApplication.class, args);
    }
}

2、实现视频上传

2.1、后端

2.1.1、创建常量类

@Component
public class ConstantVodUtils implements InitializingBean {

    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;

    @Value("${aliyun.vod.file.keyid}")
    private String accessKeyId;

    @Value("${aliyun.vod.file.keysecret}")
    private String accessKeySecret;

    @Override
    public void afterPropertiesSet() throws Exception {
        ACCESS_KEY_ID = accessKeyId;
        ACCESS_KEY_SECRET = accessKeySecret;
    }
}

2.1.2、上传视频到阿里云

VodService

public interface VodService {

    /**
     * 上传视频到阿里云
     * @param file 视频文件
     * @return 上传后的视频ID
     */
    String uploadVideo(MultipartFile file);
    
}

VodServiceImpl

@Service
public class VodServiceImpl implements VodService {

    /**
     * 上传视频到阿里云
     * @param file 视频文件
     * @return 上传后的视频ID
     */
    @Override
    public String uploadVideo(MultipartFile file) {
        try {
            String accessKeyId = ConstantVodUtils.ACCESS_KEY_ID;
            String accessKeySecret = ConstantVodUtils.ACCESS_KEY_SECRET;
            String fileName = file.getName();   // 上传文件输入流
            String title = fileName.substring(0, fileName.lastIndexOf("."));;  // 阿里云的文件名
            InputStream inputStream = file.getInputStream();

            UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, 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;
        }
    }

}

VodController

@RestController
@CrossOrigin
@RequestMapping("/vod/video")
@Api(description="阿里云视频点播微服务")
public class VodController {

    @Autowired
    private VodService vodService;

    /**
     * 上传视频到阿里云
     * @param file 视频文件
     * @return
     */
    @ApiOperation("上传视频到阿里云")
    @PostMapping("/uploadAliyunVideo")
    public R uploadAliyunVideo(MultipartFile file) {
        String videoId = vodService.uploadVideo(file);
        return R.ok().data("videoId", videoId);
    }

}

2.2、配置 nginx

在 nginx.conf 中的 server{} 中配置

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

在 server{} 的 server_name 下配置

client_max_body_size 1024m;

2.3、前端

2.3.1、上传视频组件

src\views\edu\course\chapter.vue

                <el-form-item label="上传视频">
                    <el-upload 
                        :on-success="handleVodUploadSuccess" 
                        :on-remove="handleVodRemove" 
                        :before-remove="beforeVodRemove"
                        :on-exceed="handleUploadExceed" 
                        :file-list="fileList" 
                        :action="BASE_API +'/vod/video/uploadAliyunVideo'" 
                        :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>

2.3.2、方法定义

首先在 data 中定义

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

然后定义方法

            /**
             * 上传视频成功调用的方法:赋值上传后视频的ID及文件名
             */
            handleVodUploadSuccess(response, file, fileList) {
                this.video.videoSourceId = response.data.videoId;
                this.video.videoOriginalName = file.name;
            },

            // 试图上传多于一个视频
            handleUploadExceed(files, fileList) {
                this.$message.warning('想要重新上传视频,请先删除已上传的视频');
            },

3、视频删除

3.1、后端

3.1.1、初始化阿里云视频点播客户端

public class InitVodClient {

    /**
     * 初始化阿里云视频点播客户端
     * @param accessKeyId
     * @param accessKeySecret
     * @return
     * @throws ClientException
     */
    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;
    }

}

3.1.2、根据视频 ID 删除阿里云视频

官方文档:媒资管理

    /**
     * 根据视频ID删除阿里云中的视频
     * @param videoId
     * @return
     */
    @DeleteMapping("/{videoId}")
    public R deleteAliyunVideo(
            @ApiParam(name = "videoId", value = "视频ID", required = true) @PathVariable String videoId
    ) {
        try {
            // 初始化客户端
            DefaultAcsClient client = InitVodClient.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);

            // 创建删除视频 request 对象
            DeleteVideoRequest request = new DeleteVideoRequest();

            // 像 request 对象设置视频ID
            request.setVideoIds(videoId);

            // 调用初始化对象方法实现删除
            client.getAcsResponse(request);

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

3.2、前端

3.2.1、定义 API

src\api\edu\video.js

    /**
     * 根据视频ID删除阿里云中的视频
     * @param {*} videoId 
     * @returns 
     */
    deleteAliyunVod(videoId) {
        return request({
            url: `/vod/video/${videoId}`,
            method: 'DELETE',
        })
    }

3.2.2、定义组件方法

            /**
             * 上传视频时删除列表中的视频
             */
            beforeVodRemove(file, fileList) {
                return this.$confirm(`确定移除 ${file.name}?`);
            },

            /**
             * 根据视频ID删除阿里云中的视频
             */
            handleVodRemove() {
                video.deleteAliyunVod(this.video.videoSourceId)
                    // 删除成功
                    .then(response => {
                        // 提示信息
                        this.$message({
                            type: 'success',
                            message: '删除视频成功!'
                        });

                        // 清空文件列表
                        this.fileList = [];

                        // 初始化小节中的视频ID和名称
                        this.video.videoSourceId = '';
                        this.video.videoOriginalName = '';
                    })
                    // 删除失败
                    .catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消删除'
                        });
                    });
            } 

有关谷粒学院 —— 10、课程管理:整合阿里云视频点播的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  4. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  5. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  6. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  7. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  8. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  9. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  10. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

随机推荐