我工作的一个项目,以获得从视频缩略图,然后在主页上显示它们。
缩略图在文件夹上传正确生成,但他们没有在主页显示。我收到找不到错误404。
贝娄是JeutrollServiceImp用于从视频在HTML获取缩略图的代码,我使用的是图像的硬编码名称为测试的purprose。
import com.jeutroll.dao.UserRepository;
import com.jeutroll.dao.VideoRepository;
import com.jeutroll.entities.Video;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@Service
@Transactional
public class JeutrollServiceImp implements JeutrollService
{
public static String uploadDirectory= System.getProperty("user.home") + "/uploads";
@Autowired
private UserRepository userRepository;
@Autowired
private VideoRepository videoRepository;
@Override
public Page<Video> browseVideos(String aInCategory, int page, int size)
{
return videoRepository.listVideos(aInCategory, new PageRequest(page, size));
}
@Override
public Video browseVideo(String aTitle)
{
return null;
}
@Override
public void uploadVideo(Video aInVideo)
{
}
@Override
public com.jeutroll.entities.User findUserByEmail(String email)
{
return userRepository.findByEmail(email);
}
@Override
public String retriveThumbnailFromVideo(String videoPath)
{
String thumbnailPath;
File lImgFile = null;
FFmpegFrameGrabber g = new FFmpegFrameGrabber(videoPath);
try
{
g.start();
// on fait défiler les 10 premières frame
for (int i = 0; i < 100; i++)
{
g.grab();
}
Frame lFrame = g.grabImage();
BufferedImage lBufferedImage = new Java2DFrameConverter().convert(lFrame);
// on enregistre la 101ième
Path path = Paths.get(uploadDirectory,"life_" + System.currentTimeMillis() + ".png" );
//lImgFile = new File("/resources/static/life_" + System.currentTimeMillis() + ".png");
lImgFile = new File(path.toString());
ImageIO.write(lBufferedImage, "png", lImgFile);
// récupération de la durée de la vidéo
float duration = (float) g.getLengthInTime() / 1000000;
g.stop();
}
catch (Exception e)
{
// TODO Auto-generated catch block
System.err
.println("La création de la miniature n'a pas pu être effectuée!");
e.printStackTrace();
}
return lImgFile.getName();
}
@Override
public void uploadVideos(String aInFilePath)
{
// storageService.store(file);
}
}
WebConfigurer类
package com.jeutroll.configuration;
import com.jeutroll.service.JeutrollServiceImp;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
public class WebConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploads/**").addResourceLocations("file:/" + JeutrollServiceImp.uploadDirectory);
}
}
在这里,我使用的是已经在外部文件夹中现有的磁盘上的视频。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="template1.html">
<head>
<meta charset="UTF-8">
<title>Jeutroll</title>
</head>
<body>
<div layout:fragment="content">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 text-center">
<h2 class="section-title uppercase"> Projets Réalisés</h2>
</div>
</div>
<section class="row" th:if="${videos}">
<div class="col-xs-12 col-sm-3 col-md-4 col-lg-4" th:each="v:${videos}">
<a href="#" class="thumbnail"><img src="/uploads/life_1549107645227.png" alt="Image 2" width="500px " >
<div class="caption">
<span class="cat-link">categorie</span>
<span class="separator">|</span>
<span class="pub-date">6 janvier 2019</span>
<span class="glyphicon glyphicon-comment"></span>
</div>
<div class="rating">
</div>
</a>
</div>
</section>
</div>
</div>
</body>
</html>
被卡住这个问题小时后,我终于想通了。主要的问题是,我没有在课堂WebConfigurer添加@EnableWebMvc。二是图像目录是不正确的。我执行在Windows操作系统上我的项目,我用System.getProperty(“的user.home”)+“/上传”;代替System.getProperty( “的user.home”)+ “\上传”;
因为它是一个经常性的主题。我决定写一个例子这种情况。我家它将帮助。 http://mkaroune.e-monsite.com/pages/spring/get-images-from-external-folder-on-disk.html
@Ahmed是该方法返回正确的图像路径。
我建议你看一看Spring Content。这个社区项目可以让你的内容使用相同的编程模型春数据实体(即非结构化如视频数据)相关联。
这是很简单添加到您现有的项目,它会给你同样的简单的编程模型春季数据,在存储的抽象(因此它可以在任何存储春内容支持存储)和一堆其他功能开箱即用的像REST的端点支持视频流。
如果你有兴趣在这里是如何,我认为你可以做到这一点(假设春季启动)。
依赖,加入到项目中: -
pom.hml
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs-boot-starter</artifactId>
<version>0.5.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.5.0</version>
</dependency>
配置文件存储:
store config.Java
@Configuration
@EnableFilesystemStores
public class EnableFilesystemStoresConfig {
@Bean
File filesystemRoot() {
try {
return new File(JeutrollServiceImp.uploadDirectory);
} catch (IOException ioe) {}
return null;
}
@Bean
FileSystemResourceLoader fileSystemResourceLoader() {
return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
}
}
关联内容与你的实体:
@Entity
public class Video {
@Id @GeneratedValue
private Long id;
... other Spring Data fields ...
// associate the video
@ContentId
private UUID contentId;
@ContentLength
private Long contentLength;
@Mimetype
private String mimeType;
// associate thumbnails
private Thumbnail thumbnail;
...
}
@Entity
public class Thumbnail {
@ContentId
private UUID contentId;
@ContentLength
private Long contentLength;
@MimeType
private String mimeType;
}
创建一个音像店和缩略图店:
video store.Java/thumbnail store.Java
@StoreRestResource(path="videoContent")
public interface VideoStore extends ContentStore<Video,UUID> {
}
public interface ThumbnailStore extends ContentStore<Thumbnail,UUID> {
}
该spring-content-fs-boot-starter
依存度将导致春季内容注入基于文件系统的实现,所以你不必担心这些自己实施。此外,spring-content-rest
依赖性将导致弹簧内容也注入@Controller
的实施方式中前向HTTP请求到VideoStore
和ThumbnailStore
的分别的方法。
所以,你现在有一个功能齐全(POST,PUT,GET,DELETE)基于REST的视频服务在/videoContent
将使用VideoStore
检索(和存储)的视频在JeutrollServiceImp.uploadDirectory
您的服务器上。
所以:
POST /videoContent/ -F "image=@/some/path/to/a/video.mp4"
将上传video.mp4
并将其添加到您的上传目录。
GET /videoContent/{videoId}
将再次得到它,其余的店面终端支持范围请求,因此HTML5视频控件将适当工作。
对于缩略图,你可以添加处理,生成和缩略图存储在一个注释存储事件处理程序: -
@Configuration
public class ThumbnailConfig {
@Bean
public StoreEventHandler thumbnailEventHandler() {
return new ThumbnailEventHandler();
}
@StoreEventHandler
public static class ThumbnailEventHandler {
@Autowired
VideoRepository videoRepository;
@Autowired
VideoStore videoStore;
@Autowired
ThumbnailStore thumnailStore;
@HandleAfterSetContent
public void handleAfterSetContent(Video video) {
BufferedImage img = // use modfied retrieveThumbnailFromVideo(videoStore.getContent(video));
Thumbnail thumbnail = new Thumbnail();
thumbnail.setMimeType("png")
thumbnail.setContent(thumbnail, toInputStream(img))
video.setThumbnail(thumbnail)
videoRepository.save(video);
}
}
}
之后每个视频存储其缩略图然后将可通过:
GET /videoContent/{videoId}/thumbnail
要么:
GET /videoContent/{videoId}/thumbnail/{contentId}
正如我们存储的MIME类型这些URL将可用作在你的HTML标准的src
。
所以:
变为:
HTH