web-dev-qa-db-ja.com

Spring MVCでビデオを返し、html5 <video>タグを使用してナビゲートできるようにするにはどうすればよいですか?

Webサーバー(Tomcat)にファイルがあり、タグを作成した場合、ビデオを視聴し、一時停止し、ナビゲートし、終了後に再起動できます。

しかし、RESTインターフェイスを作成して、要求時にビデオファイルを送信し、そのURLをタグに追加すると、再生と一時停止のみが可能になります。巻き戻しなし、早送りなし、移動しない、何もありません。

それで、これを修正する方法はありますか?どこかに行方不明ですか?

ビデオファイルはRESTインターフェイスと同じサーバーにあり、RESTインターフェイスはセッションをチェックし、検索後にビデオを送信しますどちらを送信するか。

これらは私がこれまでに試みた方法です。それらはすべて機能しますが、ナビゲートを許可するものはありません。

方法1、ResponseEntity:

/*
 * This will actually load the whole video file in a byte array in memory,
 * so it's not recommended.
 */
@RequestMapping(value = "/{id}/preview", method = RequestMethod.GET)
@ResponseBody public ResponseEntity<byte[]> getPreview1(@PathVariable("id") String id, HttpServletResponse response) {
    ResponseEntity<byte[]> result = null;
    try {
        String path = repositoryService.findVideoLocationById(id);
        Path path = Paths.get(pathString);
        byte[] image = Files.readAllBytes(path);

        response.setStatus(HttpStatus.OK.value());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(image.length);
        result = new ResponseEntity<byte[]>(image, headers, HttpStatus.OK);
    } catch (Java.nio.file.NoSuchFileException e) {
        response.setStatus(HttpStatus.NOT_FOUND.value());
    } catch (Exception e) {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
    return result;
}

方法2、ストリームコピー:

/*
 * IOUtils is available in Apache commons io
 */
@RequestMapping(value = "/{id}/preview2", method = RequestMethod.GET)
@ResponseBody public void getPreview2(@PathVariable("id") String id, HttpServletResponse response) {
    try {
        String path = repositoryService.findVideoLocationById(id);
        File file = new File(path)
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-Disposition", "attachment; filename="+file.getName().replace(" ", "_"));
        InputStream iStream = new FileInputStream(file);
        IOUtils.copy(iStream, response.getOutputStream());
        response.flushBuffer();
    } catch (Java.nio.file.NoSuchFileException e) {
        response.setStatus(HttpStatus.NOT_FOUND.value());
    } catch (Exception e) {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}

方法3、FileSystemResource:

@RequestMapping(value = "/{id}/preview3", method = RequestMethod.GET)
@ResponseBody public FileSystemResource getPreview3(@PathVariable("id") String id, HttpServletResponse response) {
    String path = repositoryService.findVideoLocationById(id);
    return new FileSystemResource(path);
}
24
Calabacin

HTTPレジュームダウンロード機能はあなたの友人かもしれません。以前にも同じ問題がありました。 http範囲を実装した後、ビデオのナビゲーションが可能になりました:

http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html

5
user3395533

非静的リソースを処理するための簡単なソリューション:

@SpringBootApplication
public class DemoApplication {

    private final static File MP4_FILE = new File("/home/ego/bbb_sunflower_1080p_60fps_normal.mp4");

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Controller
    final static class MyController {

        @Autowired
        private MyResourceHttpRequestHandler handler;

        // supports byte-range requests
        @GetMapping("/")
        public void home(
                HttpServletRequest request,
                HttpServletResponse response
        ) throws ServletException, IOException {

            request.setAttribute(MyResourceHttpRequestHandler.ATTR_FILE, MP4_FILE);
            handler.handleRequest(request, response);
        }

        // does not support byte-range requests
        @GetMapping(path = "/plain", produces = "video/mp4")
        public FileSystemResource plain() {

            return new FileSystemResource(MP4_FILE);
        }
    }

    @Component
    final static class MyResourceHttpRequestHandler extends ResourceHttpRequestHandler {

        private final static String ATTR_FILE = MyResourceHttpRequestHandler.class.getName() + ".file";

        @Override
        protected Resource getResource(HttpServletRequest request) throws IOException {

            final File file = (File) request.getAttribute(ATTR_FILE);
            return new FileSystemResource(file);
        }
    }
}

(Spring Boots LogFileMvcEndpoint に触発され、多かれ少なかれPaul-Warrens(@ paul-warren) StoreByteRangeHttpRequestHandler 後で見つけました)。

これがSpringで近い将来にサポートされることを願っています https://jira.spring.io/browse/SPR-13834 を参照してください(投票してください)。

12
bgraves

私はこれが古い投稿であることを知っていますが、同じ/類似の質問をしている他の誰かに役立つ場合に備えて。

今日では、ビデオストリーミングをネイティブでサポートする Spring Content のようなプロジェクトがあります。最も簡単な実装に必要なすべてのコードは次のようになります:-

@StoreRestResource(path="videos")
public interface VideoStore extends Store<String> {}

そして、これはJava APIとRESTエンドポイントのセットを作成するのに十分であり、ビデオのストリームのPUT/POST、GET、DELETEを可能にします。 GETはバイト範囲をサポートし、HTML5ビデオプレーヤーなどで適切に再生されます。

3
Paul Warren

実際、<video>タグのビデオコントロールを表示するのはフロントエンドです。

特別なビデオ形式の各ブラウザには、デフォルトのコントロールパネルがあります。

Htmlとcssを使用して、メディアAPIで独自のコントロールを作成できます。 Media api

From Div into HTML5 [デフォルトでは、<video>要素はいかなる種類のプレーヤーコントロールも公開しません。プレーンな古いHTML、CSS、JavaScriptで独自のコントロールを作成できます。 <video>要素には、play()やpause()などのメソッドと、currentTimeと呼ばれる読み取り/書き込みプロパティがあります。読み取り/書き込みボリュームとミュートされたプロパティもあります。したがって、独自のインターフェースを構築するために必要なものがすべて揃っています。]

0
Sho