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

您所在的位置:网站首页 csdn怎么上传视频 使用fastdfs上传视频并使用FFmpegFrameGrabberFrameGrabber在上传视频时截图作为封面

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

2023-08-28 13:37| 来源: 网络整理| 查看: 265

使用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项目,导入相关依赖 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf net.oschina.zcx7878 fastdfs-client-java 1.27.0.0 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-data-jdbc org.projectlombok lombok provided org.bytedeco javacv 0.8 org.apache.httpcomponents httpcore 4.4.9 org.springframework spring-test 5.1.6.RELEASE 3.往resources中添加一个fastdfs的配置文件fastdfs-client.properties ## fastdfs-client.properties fastdfs.connect_timeout_in_seconds = 5 fastdfs.network_timeout_in_seconds = 30 fastdfs.charset = UTF-8 fastdfs.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 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文件了

在这里插入图片描述

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

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; @Autowired VideoSaveServiceImpl(VideoSaveMapper videoSaveMapper){ this.videoSaveMapper = videoSaveMapper; } @Value("${fastdfs.nginx.host}") String nginxHost; @Override public 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; @Autowired VideoUploadController(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 单文件上传

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

在这里插入图片描述

运行截图:

在这里插入图片描述

在这里插入图片描述

将url在浏览器打开

视频

在这里插入图片描述 视频截图 在这里插入图片描述

我爱的iu



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3