使用fastdfs上传视频并使用FFmpegFrameGrabberFrameGrabber在上传视频后,截图作为封面

最近为了参加一个比赛,需要一个视频上传功能,所以查了很多。以下为一个小demo

使用工具:idea,阿里云服务器,fastdfs

服务器部分

1. 在阿里云服务器上安装fastdfs分布式文件管理系统

安装方法参考https://www.cnblogs.com/handsomeye/p/9451568.html

安装fastdfs踩过太多坑了,安装一定要注意,storage.conf,client.conf,tracker.conf这三个配置文件的路径设置什么的,然后要搭配nginx实现访问,nginx的配置文件nginx.conf也要注意

后端部分

fastdfs和nginx配置并测试好了之后,开始写测试代码

1.idea文件结构如图

2.在idea新建springboot项目,导入相关依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--fastdfs依赖--><dependency><groupId>net.oschina.zcx7878</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27.0.0</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- 上传视频截图依赖--><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>0.8</version></dependency><!--file转化为MultipartFile file的依赖--><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.9</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.6.RELEASE</version></dependency></dependencies>

3.往resources中添加一个fastdfs的配置文件fastdfs-client.properties

## fastdfs-client.propertiesfastdfs.connect_timeout_in_seconds = 5
fastdfs.network_timeout_in_seconds = 30fastdfs.charset = UTF-8fastdfs.http_anti_steal_token = false
fastdfs.http_secret_key = FastDFS1234567890
fastdfs.http_tracker_http_port = 80#你服务器的地址
fastdfs.tracker_servers = xx.xx.xx.xx:22122## Whether to open the connection pool, if not, create a new connection every time
fastdfs.connection_pool.enabled = true## max_count_per_entry: max connection count per host:port , 0 is not limit
fastdfs.connection_pool.max_count_per_entry = 500## connections whose the idle time exceeds this time will be closed, unit: second, default value is 3600
fastdfs.connection_pool.max_idle_time = 3600## Maximum waiting time when the maximum number of connections is reached, unit: millisecond, default value is 1000
fastdfs.connection_pool.max_wait_time_in_ms = 1000

4.application.yml

5.编写FastDFSVideoUtils工具类

import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;public class FastDFSVideoUtils {private static StorageClient1 client1;private static StorageServer storeStorage;private static StorageServer storageServer;static{try {ClientGlobal.initByProperties("fastdfs-client.properties");TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();storeStorage = trackerClient.getStoreStorage(trackerServer);String storageIp = storeStorage.getSocket().getInetAddress().getHostAddress();Integer port = storeStorage.getSocket().getPort();//0表示上传到图片目录,1表示上传到视频目录storageServer = new StorageServer(storageIp, port, 1);client1 = new StorageClient1(trackerServer, storageServer);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}}public static String upload(MultipartFile file){String oldName = file.getOriginalFilename();try {return client1.upload_file1(file.getBytes(), oldName.substring(oldName.lastIndexOf(".")+1),null);} catch (IOException e) {e.printStackTrace();} catch (MyException e) {e.printStackTrace();}return null;}
}

还有截图工具类:


import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.UUID;import javax.imageio.ImageIO;import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.springframework.web.multipart.MultipartFile;public class ScreenshotUtils {/*** 获取指定视频的帧并保存为图片至指定目录* @param videourl  源视频文件路径* @throws Exception*/public static String fetchFrame(String videourl,MultipartFile file)throws Exception {//获取当前系统时间,类似new Date(),效率比较好long start = System.currentTimeMillis();//储存截图的文件//window下用\\,电脑要有D盘,不然换成你想要的盘File targetFile = new File("D:\\video\\cutpic");if(!targetFile.exists()){targetFile.mkdirs();}String filename = file.getOriginalFilename();String filenamePrefix = filename.substring(0, filename.lastIndexOf("."));//创建储存截图的图片文件路径//window下用\\String coverimgPath = targetFile.getPath()+ "\\" + UUID.randomUUID().toString()+filenamePrefix + ".jpg";File cutpic = new File(coverimgPath);//FFmpegFrameGrabb读取时间随机截图类FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videourl);ff.start();// 表示视频的总图片数量int lenght = ff.getLengthInFrames();int i = 0;Frame f = null;while (i < lenght) {// 过滤前5帧,避免出现全黑的图片,依自己情况而定f = ff.grabFrame();if ((i > 5) && (f.image != null)) {break;}i++;}IplImage img = f.image;int owidth = img.width();int oheight = img.height();// 对截取的帧进行等比例缩放int width = 800;int height = (int) (((double) width / owidth) * oheight);BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);ImageIO.write(bi, "jpg", cutpic);//ff.flush();ff.stop();System.out.println(System.currentTimeMillis() - start);return coverimgPath;}}

6.编写mapper文件和mapper.xml

这里因为我的mybatis-config.xml有问题,不知道什么错,所以先用注解方式测试,就可以不用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.upload.demo.mapper.VideoSaveMapper"><insert id="insertVideoUrl" >INSERT INTO video(video_url,user_id,professional_name,image_url,title,create_time,collection_count,thumb_count,visit_count,comment_count)VALUES (#{videoUrl},#{userId},#{professionalName},#{imageUrl},#{title},#{createTime},#{collectionCount},#{thumbCount},#{visitCount},#{commentCount})</insert>
</mapper>

mybatis-config.xml

数据库我建在了服务器上,要先安装mysql服务在服务器上哦,结构如下,连接数据库的方法请自行百度

7.VideoSaveService和VideoSaveServiceImpl

import com.upload.demo.config.FastDFSUtils;
import com.upload.demo.config.FastDFSVideoUtils;
import com.upload.demo.config.ScreenshotUtils;
import com.upload.demo.mapper.VideoSaveMapper;
import com.upload.demo.pojo.VideoSave;
import com.upload.demo.service.VideoSaveService;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
public class VideoSaveServiceImpl implements VideoSaveService {private VideoSaveMapper videoSaveMapper;@AutowiredVideoSaveServiceImpl(VideoSaveMapper videoSaveMapper){this.videoSaveMapper = videoSaveMapper;}@Value("${fastdfs.nginx.host}")String nginxHost;@Overridepublic Integer insertVideo(MultipartFile file,Integer userId,String professionalName,String title,Integer collectionCount,Integer thumbCount,Integer visitCount,Integer commentCount) throws Exception {final String fileId = FastDFSVideoUtils.upload(file);String videoUrl = nginxHost + fileId;Date date = new Date();//HH为24小时制,hh为12小时制SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :HH:mm:ss");String createTime = dateFormat.format(date);//将截图转化为file对象,再将file对象转化为MockMultipartFile 对象String cutpicPath = ScreenshotUtils.fetchFrame(videoUrl, file);File cutpic = new File(cutpicPath);FileInputStream fileInputStream = new FileInputStream(cutpic);MockMultipartFile cutPicFile = new MockMultipartFile(cutpic.getName(),cutpic.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);//FastDFSUtils将上面转化的MockMultipartFile 对象上传final String cutPicfileId = FastDFSVideoUtils.upload(cutPicFile);String imageUrl = nginxHost + cutPicfileId;return videoSaveMapper.insertVideoUrl(videoUrl,userId,professionalName,imageUrl,title,createTime,collectionCount,thumbCount,visitCount,commentCount);}
}

8.VideoUploadController控制器代码

import com.upload.demo.config.FastDFSUtils;
import com.upload.demo.config.FastDFSVideoUtils;
import com.upload.demo.config.ScreenshotUtils;
import com.upload.demo.service.VideoSaveService;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.FileInputStream;@Controller
public class VideoUploadController {@Value("${fastdfs.nginx.host}")String nginxHost;private VideoSaveService videoSaveService;@AutowiredVideoUploadController(VideoSaveService videoSaveService){this.videoSaveService = videoSaveService;}@PostMapping("/uploadVideo")public String UploadVideo(MultipartFile file,@RequestParam(value="userId",defaultValue="1") Integer userId,@RequestParam(value="professionalName",defaultValue="hhh") String professionalName,@RequestParam(value="title",defaultValue="123") String title,@RequestParam(value="collectionCount",defaultValue="0") Integer collectionCount,@RequestParam(value="thumbCount",defaultValue="0") Integer thumbCount,@RequestParam(value="visitCount",defaultValue="0") Integer visitCount,@RequestParam(value="commentCount",defaultValue="0") Integer commentCount) throws Exception {if(videoSaveService.insertVideo(file,userId,professionalName,title,collectionCount,thumbCount,visitCount,commentCount)==1){return "/success";}else {return "/false";}}
}

前端部分

都要放在template文件夹下,控制器要有一个跳转到index.html下的方法,return就行,很简单。

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta http-equiv="Content-type" content="text/html; charset=UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><title>单文件上传</title>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data"><input type="file" name="file"><br><input type="submit" value="上传头像">
</form><form method="post" action="/uploadVideo" enctype="multipart/form-data"><input type="file" name="file"><br><input type="submit" value="上传视频">
</form>
</body></html>

成功跳转到succes.html,失败跳转false.html

运行截图:

将url在浏览器打开

视频


视频截图

我爱的iu

使用fastdfs上传视频并使用FFmpegFrameGrabberFrameGrabber在上传视频时截图作为封面相关推荐

  1. yii2.0使用ueditior完成上传单张,多张图片,上传视频等操作

    一.前言 由于工作需求需要集成富文本编辑器,本来是想要选用之前用过的WangEditor的,但是考虑到WangEditor还是比较小众,所以最终选择了没用过的Uedtor,这篇文章主要讲述了Yii2. ...

  2. 云服务器网站不能够上传视频,网站的视频要存到云服务器上吗

    网站的视频要存到云服务器上吗 内容精选 换一换 云服务器怎么选?云服务购买选择的时候主要根据以下方面来确定:服务器区域.宽带.核心数.线路.处理器.业务应用场景等方面来综合考虑.对于个人或者中小企业来 ...

  3. FastDFS:Java客户都实现文件的上传、下载、修改、删除

    FastDFS:Java客户都实现文件的上传.下载.修改.删除 <project xmlns="http://maven.apache.org/POM/4.0.0" xmln ...

  4. 腾讯视频下载安装链接_腾讯视频怎么上传视频

    今天继续给大家分享腾讯视频方面的内容.腾讯视频播放器是腾讯视频官方推出的一款视频客户端,致力于为用户提供高清.流畅.丰富的专业视频服务,在这里您可在线享受腾讯视频网站内全部免费高清正版视频.使用腾讯视 ...

  5. 腾讯视频下载安装_如何上传视频到腾讯视频平台

    播放器软件很多,本文小编给大家推荐腾讯视频.我们可以在腾讯视频播放器上,观看各种电视剧.电影.综艺节目等内容.里面的大部分视频都是免费的,部分独播大剧可能会存在vip收费的情况,这也是无法避免的.腾讯 ...

  6. android 视频录制和上传,关于android实时视频录制与上传 .

    关于android的实时视频录制现在网上炒的很火,我想把自己学习研究的一个视频录制的demo 的心得与大家分享一下 使用的是MediaRecorder 以及使用SurfaceView进行录制的. 视频 ...

  7. 微信里文件小程序导不出来_懒得打开电脑传文件?这四类小程序把这事解决了-小程序视频怎么发在电脑上...

    在<小程序说·能力百科全书>前两期中,我们说到了小程序的"蓝牙能力".弱网环境下,它是篮球场上力挽狂澜的"第六人":出行场景中,它还能化身你的&qu ...

  8. 微信小程序-从相册获取图片,视频 使用相机拍照,录像上传+服务器(nodejs版)接收

    在本文 微信小程序-从相册获取图片 使用相机拍照 本地图片上传之前需要看看 微信小程序-获取用户session_key,openid,unionid - 后端为nodejs 代码封装是在上文添加的. ...

  9. 服务器违反了协议怎么办,微云里面的视频被和谐了怎么办 上传视频违反协议解决方法...

    1.第一步:首先找到自己的小号,双击打开聊天窗口.(如下图所示:) 2.第二步:选择"传送文件"选项.(如下图所示:) 3.第三步:点击"传送文件",后选择&q ...

  10. 微信小程录制视频上传服务器,微信小程序-从相册获取图片,视频使用相机拍照,录像上传+服务器nodejs版接收-微信小程序视频上传功能-微信小程序视频上传...

    在本文微信小程序-从相册获取图片使用相机拍照本地图片上传之前需要看看微信小程序-获取用户session_key,openid,unionid-后端为nodejs代码封装是在上文添加的.本文知识点:1. ...

最新文章

  1. 玩转以太坊(Ethereum)的测试网络
  2. Linux命令(4):cat命令
  3. 在派生类中引发基类事件
  4. C语言数组中两个数字之间的最大差的算法(附完整源码)
  5. 一天的学习成果:hash输出,dcache工作原理,include的home directory,fist optype的含义...
  6. python语音识别的第三方库_python标准库+内置函数+第三方库: 7.音频处理
  7. C#实现浮动和多标签窗体解决方案---使用Dockpanel
  8. jena 开发之 mysql数据导入_在Jena框架下基于MySQL数据库实现本体的存取操作
  9. 鸿蒙推送荣耀,华为鸿蒙首批推送机型8款,荣耀“避嫌”,不在首批名单
  10. Streamlit--python中的前端
  11. Navicat Premium 12破解方法
  12. 9106w android7,三星n9106w官方原版固件rom刷机包_三星n9106w系统线刷包
  13. Android 隐藏App的图标
  14. Ant Design之表格动态合并行
  15. long型和int型的区别
  16. 我读Saliency Filters cvpr 2012
  17. undefined reference to 'function'及解决办法
  18. free ebooks: http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books
  19. HDFS Router-based Federation
  20. [Jzoj] 3461. 小麦亩产一千八

热门文章

  1. 桌面计算机打开无响应,在win7系统中桌面无响应的几种解决方法
  2. DevExpress Office File API v20.1新版亮点:增强PDF Document API
  3. 微信小程序---简约音乐播放器
  4. 【车牌识别】基于模板匹配算法实现新能源车牌识别matlab源码
  5. Win10如何取消开机密码?Win10取消开机密码步骤
  6. 2018我们讲一下百度云BAE专业引擎的使用
  7. 使用百度BAE部署JavaWeb项目+SVN的使用
  8. 二分法解经典题目:切木头
  9. 2021年IEEE Fellow刚刚放榜!84位华人学者当选再创新高!
  10. UE4中实现鼠标单选空间中的模型、Ctrl键多选、空间打点框选功能。