Как отобразить изображение из внешней папки на HTML-странице - PullRequest
0 голосов
/ 03 февраля 2019

Я работаю над проектом, чтобы получить миниатюры из видео и затем отобразить их на домашней странице.

Миниатюры правильно генерируются при загрузке в папку, но не отображаются на домашней странице.Я получаю сообщение об ошибке 404.

Ниже приведен код JeutrollServiceImp, используемый для получения миниатюр из видео. В html я использую жесткое кодовое имя изображения для целей теста.

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>

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Я бы посоветовал вам взглянуть на Spring Content .Этот проект сообщества позволяет связать контент (то есть неструктурированные данные, такие как видео) с объектами Spring Data Entities, используя ту же модель программирования.

Это довольно просто добавить в существующий проект, и оно даст вам такое же простое программирование.модель как Spring Data, абстракция над вашим хранилищем (чтобы его можно было хранить в любой поддержке Storage Spring Content) и множество других функций OOTB, таких как конечная точка REST, которые поддерживают потоковое видео.

На случай, если вы заинтересованывот как я думаю, вы могли бы это сделать (при условии Spring Boot).

Добавить зависимости в ваш проект: -

pom.xml

    <!-- 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>

Настройка хранилища файлов:

StoreConfig.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;
   }

Создание видеоstore и магазин миниатюр:

VideoStore.java / ThumbnailStore.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Реализации на основе ilesystem, поэтому вам не нужно беспокоиться об их реализации.Более того, зависимость spring-content-rest заставит Spring Content также внедрить реализации @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}

получит его снова и сохранит остальные конечные точки, поддерживая запросы Range, чтобы элементы управления видео 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}

Когда мы сохраняем mimetype, эти URL будут использоваться как src в стандарте вашего HTML.

Итак:

Становится:

HTH

0 голосов
/ 03 февраля 2019

После долгих часов этой проблемы я наконец-то понял.Основная проблема в том, что я не добавил @EnableWebMvc в класс WebConfigurer.Во-вторых, каталог изображений был неверным.Я выполняю свой проект в ОС Windows, и я использовал System.getProperty ("user.home") + "/ uploads";вместо System.getProperty ("user.home") + "\ uploads";

, потому что это повторяющаяся тема.Я решил написать пример для этого случая.Мне домой это поможет.http://mkaroune.e -monsite.com / pages / spring / get-images-from-external-folder-on-disk.html

@ Ахмед Да, метод возвращает правильный путь к изображению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...