forked from huangkangyuan/xcEdu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4dbb889
commit 29ccc51
Showing
17 changed files
with
1,027 additions
and
0 deletions.
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
xc-service-api/src/main/java/com/xuecheng/api/media/MediaUploadControllerApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.xuecheng.api.media; | ||
|
||
import com.xuecheng.framework.domain.media.response.CheckChunkResult; | ||
import com.xuecheng.framework.model.response.ResponseResult; | ||
import io.swagger.annotations.Api; | ||
import io.swagger.annotations.ApiOperation; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@Api(value = "媒资管理接口",description = "媒资管理接口,提供文件上传、处理等接口") | ||
public interface MediaUploadControllerApi { | ||
|
||
//文件上传前的准备工作,校验文件是否存在 | ||
@ApiOperation("文件上传注册") | ||
public ResponseResult register(String fileMd5, | ||
String fileName, | ||
Long fileSize, | ||
String mimeType, | ||
String fileExt); | ||
|
||
@ApiOperation("校验分块文件是否存在") | ||
public CheckChunkResult checkChunk(String fileMd5, | ||
Integer chunk, | ||
Integer chunkSize); | ||
|
||
@ApiOperation("上传分块") | ||
public ResponseResult uploadChunk(MultipartFile file, | ||
String fileMd5, | ||
Integer chunk); | ||
|
||
@ApiOperation("合并分块") | ||
public ResponseResult mergeChunks(String fileMd5, | ||
String fileName, | ||
Long fileSize, | ||
String mimeType, | ||
String fileExt); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>xc-framework-parent</artifactId> | ||
<groupId>com.xuecheng</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
<relativePath>../xc-framework-parent/pom.xml</relativePath> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>xc-service-manage-media-processor</artifactId> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.xuecheng</groupId> | ||
<artifactId>xc-service-api</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.xuecheng</groupId> | ||
<artifactId>xc-framework-model</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.xuecheng</groupId> | ||
<artifactId>xc-framework-utils</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.xuecheng</groupId> | ||
<artifactId>xc-framework-common</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-mongodb</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-amqp</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.squareup.okhttp3</groupId> | ||
<artifactId>okhttp</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-test</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
23 changes: 23 additions & 0 deletions
23
...ssor/src/main/java/com/xuecheng/manage_media_process/ManageMediaProcessorApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.xuecheng.manage_media_process; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.boot.autoconfigure.domain.EntityScan; | ||
import org.springframework.context.annotation.ComponentScan; | ||
|
||
|
||
/** | ||
* @author Administrator | ||
* @version 1.0 | ||
* @create 2018-07-12 8:57 | ||
**/ | ||
@SpringBootApplication | ||
@EntityScan("com.xuecheng.framework.domain.media")//扫描实体类 | ||
@ComponentScan(basePackages={"com.xuecheng.api"})//扫描接口 | ||
@ComponentScan(basePackages={"com.xuecheng.manage_media_process"})//扫描本项目下的所有类 | ||
@ComponentScan(basePackages={"com.xuecheng.framework"})//扫描common下的所有类 | ||
public class ManageMediaProcessorApplication { | ||
public static void main(String[] args) { | ||
SpringApplication.run(ManageMediaProcessorApplication.class, args); | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
...edia-processor/src/main/java/com/xuecheng/manage_media_process/config/RabbitMQConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.xuecheng.manage_media_process.config; | ||
|
||
import org.springframework.amqp.core.*; | ||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; | ||
import org.springframework.amqp.rabbit.connection.ConnectionFactory; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class RabbitMQConfig { | ||
|
||
public static final String EX_MEDIA_PROCESSTASK = "ex_media_processor"; | ||
|
||
//视频处理队列 | ||
@Value("${xc-service-manage-media.mq.queue-media-video-processor}") | ||
public String queue_media_video_processtask; | ||
|
||
//视频处理路由 | ||
@Value("${xc-service-manage-media.mq.routingkey-media-video}") | ||
public String routingkey_media_video; | ||
|
||
//消费者并发数量 | ||
public static final int DEFAULT_CONCURRENT = 10; | ||
|
||
@Bean("customContainerFactory") | ||
public SimpleRabbitListenerContainerFactory containerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) { | ||
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); | ||
factory.setConcurrentConsumers(DEFAULT_CONCURRENT); | ||
factory.setMaxConcurrentConsumers(DEFAULT_CONCURRENT); | ||
configurer.configure(factory, connectionFactory); | ||
return factory; | ||
} | ||
|
||
/** | ||
* 交换机配置 | ||
* @return the exchange | ||
*/ | ||
@Bean(EX_MEDIA_PROCESSTASK) | ||
public Exchange EX_MEDIA_VIDEOTASK() { | ||
return ExchangeBuilder.directExchange(EX_MEDIA_PROCESSTASK).durable(true).build(); | ||
} | ||
//声明队列 | ||
@Bean("queue_media_video_processtask") | ||
public Queue QUEUE_PROCESSTASK() { | ||
Queue queue = new Queue(queue_media_video_processtask,true,false,true); | ||
return queue; | ||
} | ||
/** | ||
* 绑定队列到交换机 . | ||
* @param queue the queue | ||
* @param exchange the exchange | ||
* @return the binding | ||
*/ | ||
@Bean | ||
public Binding binding_queue_media_processtask(@Qualifier("queue_media_video_processtask") Queue queue, @Qualifier(EX_MEDIA_PROCESSTASK) Exchange exchange) { | ||
return BindingBuilder.bind(queue).to(exchange).with(routingkey_media_video).noargs(); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...ia-processor/src/main/java/com/xuecheng/manage_media_process/dao/MediaFileRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.xuecheng.manage_media_process.dao; | ||
|
||
import com.xuecheng.framework.domain.media.MediaFile; | ||
import org.springframework.data.mongodb.repository.MongoRepository; | ||
|
||
public interface MediaFileRepository extends MongoRepository<MediaFile,String> { | ||
} |
115 changes: 115 additions & 0 deletions
115
...-media-processor/src/main/java/com/xuecheng/manage_media_process/mq/MediaProcessTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package com.xuecheng.manage_media_process.mq; | ||
|
||
import com.alibaba.fastjson.JSON; | ||
import com.xuecheng.framework.domain.media.MediaFile; | ||
import com.xuecheng.framework.domain.media.MediaFileProcess_m3u8; | ||
import com.xuecheng.framework.utils.HlsVideoUtil; | ||
import com.xuecheng.framework.utils.Mp4VideoUtil; | ||
import com.xuecheng.manage_media_process.dao.MediaFileRepository; | ||
import org.springframework.amqp.rabbit.annotation.RabbitListener; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
@Component | ||
public class MediaProcessTask { | ||
|
||
@Value("${xc-service-manage-media.ffmpeg-path}") | ||
String ffmpeg_path; | ||
|
||
//上传文件根目录 | ||
@Value("${xc-service-manage-media.video-location}") | ||
String serverPath; | ||
|
||
@Autowired | ||
MediaFileRepository mediaFileRepository; | ||
|
||
//接收视频处理消息进行视频处理 | ||
@RabbitListener(queues="${xc-service-manage-media.mq.queue-media-video-processor}",containerFactory = "customContainerFactory") | ||
public void receiveMediaProcessTask(String msg){ | ||
//1、解析消息内容,得到mediaId | ||
Map map = JSON.parseObject(msg, Map.class); | ||
String mediaId = (String) map.get("mediaId"); | ||
//2、拿mediaId从数据库查询文件信息 | ||
Optional<MediaFile> optional = mediaFileRepository.findById(mediaId); | ||
if(!optional.isPresent()){ | ||
return ; | ||
} | ||
MediaFile mediaFile = optional.get(); | ||
//文件类型 | ||
String fileType = mediaFile.getFileType(); | ||
if(!fileType.equals("avi")){ | ||
mediaFile.setProcessStatus("303004");//无需处理 | ||
mediaFileRepository.save(mediaFile); | ||
return ; | ||
}else{ | ||
//需要处理 | ||
mediaFile.setProcessStatus("303001");//处理中 | ||
mediaFileRepository.save(mediaFile); | ||
} | ||
//3、使用工具类将avi文件生成mp4 | ||
//String ffmpeg_path, String video_path, String mp4_name, String mp4folder_path | ||
//要处理的视频文件的路径 | ||
String video_path = serverPath + mediaFile.getFilePath() + mediaFile.getFileName(); | ||
//生成的mp4的文件名称 | ||
String mp4_name = mediaFile.getFileId() + ".mp4"; | ||
//生成的mp4所在的路径 | ||
String mp4folder_path = serverPath + mediaFile.getFilePath(); | ||
//创建工具类对象 | ||
Mp4VideoUtil mp4VideoUtil =new Mp4VideoUtil(ffmpeg_path,video_path,mp4_name,mp4folder_path); | ||
//进行处理 | ||
String result = mp4VideoUtil.generateMp4(); | ||
if(result == null || !result.equals("success")){ | ||
//处理失败 | ||
mediaFile.setProcessStatus("303003"); | ||
//定义mediaFileProcess_m3u8 | ||
MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8(); | ||
//记录失败原因 | ||
mediaFileProcess_m3u8.setErrormsg(result); | ||
mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8); | ||
mediaFileRepository.save(mediaFile); | ||
return ; | ||
} | ||
|
||
//4、将mp4生成m3u8和ts文件 | ||
//String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path | ||
//mp4视频文件路径 | ||
String mp4_video_path = serverPath + mediaFile.getFilePath() + mp4_name; | ||
//m3u8_name文件名称 | ||
String m3u8_name = mediaFile.getFileId() +".m3u8"; | ||
//m3u8文件所在目录 | ||
String m3u8folder_path = serverPath + mediaFile.getFilePath() + "hls/"; | ||
HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path,mp4_video_path,m3u8_name,m3u8folder_path); | ||
//生成m3u8和ts文件 | ||
String tsResult = hlsVideoUtil.generateM3u8(); | ||
if(tsResult == null || !tsResult.equals("success")){ | ||
//处理失败 | ||
mediaFile.setProcessStatus("303003"); | ||
//定义mediaFileProcess_m3u8 | ||
MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8(); | ||
//记录失败原因 | ||
mediaFileProcess_m3u8.setErrormsg(result); | ||
mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8); | ||
mediaFileRepository.save(mediaFile); | ||
return ; | ||
} | ||
//处理成功 | ||
//获取ts文件列表 | ||
List<String> ts_list = hlsVideoUtil.get_ts_list(); | ||
|
||
mediaFile.setProcessStatus("303002"); | ||
//定义mediaFileProcess_m3u8 | ||
MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8(); | ||
mediaFileProcess_m3u8.setTslist(ts_list); | ||
mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8); | ||
|
||
//保存fileUrl(此url就是视频播放的相对路径) | ||
String fileUrl =mediaFile.getFilePath() + "hls/"+m3u8_name; | ||
mediaFile.setFileUrl(fileUrl); | ||
mediaFileRepository.save(mediaFile); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
xc-service-manage-media-processor/src/main/resources/application.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
server: | ||
port: 31450 | ||
spring: | ||
application: | ||
name: xc-service-manage-media-processor | ||
data: | ||
mongodb: | ||
uri: mongodb://root:root@localhost:27017 | ||
database: xc_media | ||
#rabbitmq配置 | ||
rabbitmq: | ||
host: 127.0.0.1 | ||
port: 5672 | ||
username: guest | ||
password: guest | ||
virtual-host: / | ||
xc-service-manage-media: | ||
mq: | ||
queue-media-video-processor: queue_media_video_processor | ||
routingkey-media-video: routingkey_media_video | ||
video-location: F:/WebStormProject/video/ | ||
ffmpeg-path: E:/ffmpeg/ffmpeg-20180227-fa0c9d6-win64-static/bin/ffmpeg.exe |
46 changes: 46 additions & 0 deletions
46
xc-service-manage-media-processor/src/main/resources/logback-spring.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<configuration> | ||
<!--定义日志文件的存储地址,使用绝对路径--> | ||
<property name="LOG_HOME" value="F:/document/logs"/> | ||
|
||
<!-- Console 输出设置 --> | ||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | ||
<encoder> | ||
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> | ||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
<charset>utf8</charset> | ||
</encoder> | ||
</appender> | ||
|
||
<!-- 按照每天生成日志文件 --> | ||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | ||
<!--日志文件输出的文件名--> | ||
<fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern> | ||
</rollingPolicy> | ||
<encoder> | ||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<!-- 异步输出 --> | ||
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> | ||
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> | ||
<discardingThreshold>0</discardingThreshold> | ||
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> | ||
<queueSize>512</queueSize> | ||
<!-- 添加附加的appender,最多只能添加一个 --> | ||
<appender-ref ref="FILE"/> | ||
</appender> | ||
|
||
|
||
<logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"> | ||
<appender-ref ref="CONSOLE"/> | ||
</logger> | ||
<root level="info"> | ||
<!--<appender-ref ref="ASYNC"/>--> | ||
<appender-ref ref="FILE"/> | ||
<appender-ref ref="CONSOLE"/> | ||
</root> | ||
</configuration> |
Oops, something went wrong.