国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java后端接口返回視頻流,使用video組件播放視頻,實(shí)現(xiàn)分段下載

這篇具有很好參考價(jià)值的文章主要介紹了Java后端接口返回視頻流,使用video組件播放視頻,實(shí)現(xiàn)分段下載。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

視頻文件保存在不為人知的地方,總之前端不能直接訪問(wèn)的位置,需要通過(guò)后端接口取出來(lái)再返回給前端。
前端這樣子播放

<video controls="controls" controls="controls">
  <source src="http://ip:port/xxxxxxx" type="video/mp4" />
</video>

src=后端接口
如果后端直接這樣子寫

	//path為本地文件路勁
    public void play(String path, HttpServletRequest request, HttpServletResponse response) {
        //獲取視頻文件流
        FileInputStream fileInputStream = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            fileInputStream = new FileInputStream(new File(path));
        byte[] cache = new byte[1024];
            response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
            response.setHeader(HttpHeaders.CONTENT_LENGTH, fileInputStream.available()+"");
        int flag;
        while ((flag = fileInputStream.read(cache)) != -1) {
            outputStream.write(cache, 0, flag);
        }
        outputStream.flush();
        outputStream.close();
        }catch (Exception e){
            log.error("文件傳輸錯(cuò)誤", e);
            throw new RuntimeException("文件傳輸錯(cuò)誤");
        } finally{
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    log.error("流釋放錯(cuò)誤", e);
                }
            }
            if(fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    log.error("文件流釋放錯(cuò)誤", e);
                }
            }
        }
    }

小視頻問(wèn)題不大,視頻大的話會(huì)卡頓很久,查看請(qǐng)求發(fā)現(xiàn)會(huì)先請(qǐng)求下載完整視頻后開(kāi)始播放。而且不能拖動(dòng)進(jìn)度條進(jìn)行播放。追及原因是因?yàn)関ideo會(huì)先發(fā)送一個(gè)探測(cè)請(qǐng)求獲取視頻的大小、長(zhǎng)度等信息,之后才開(kāi)始進(jìn)行播放。不能拖動(dòng)進(jìn)度條播放是因?yàn)楂@取視頻接口不支持?jǐn)帱c(diǎn)傳輸所以只能依次觀看。
http請(qǐng)求就有相關(guān)斷點(diǎn)傳輸?shù)膮f(xié)議,http協(xié)議狀態(tài)碼206就是實(shí)現(xiàn)斷點(diǎn)傳輸?shù)膮f(xié)議,Http請(qǐng)求頭部需要指定獲取數(shù)據(jù)的范圍: Range: bytes=first-end,first,開(kāi)始數(shù)據(jù)的索引位置,end,結(jié)束數(shù)據(jù)的索引位置。Http響應(yīng)需要指定范圍響應(yīng)頭:content-range bytes first-end,并且http狀態(tài)碼設(shè)置為206。
所以實(shí)現(xiàn)視頻斷點(diǎn)播放的大概思路為,先識(shí)別http請(qǐng)求頭是否攜帶range請(qǐng)求頭,如果攜帶則表示請(qǐng)求需要進(jìn)行斷點(diǎn)下載,識(shí)別出斷點(diǎn)的位置后使用隨機(jī)讀取文件類RandomAccessFile進(jìn)行一定范圍的讀寫,之后返回設(shè)置Content-Range請(qǐng)求頭表示返回?cái)?shù)據(jù)的范圍,并設(shè)置http狀態(tài)碼為206表示斷點(diǎn)傳輸。代碼如下文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-530095.html

	//path為本地文件路勁
	public void play(String path, HttpServletRequest request, HttpServletResponse response) {

        RandomAccessFile targetFile = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            response.reset();
            //獲取請(qǐng)求頭中Range的值
            String rangeString = request.getHeader(HttpHeaders.RANGE);

            //打開(kāi)文件
            File file = new File(path);
            if (file.exists()) {
                //使用RandomAccessFile讀取文件
                targetFile = new RandomAccessFile(file, "r");
                long fileLength = targetFile.length();
                long requestSize = (int) fileLength;
                //分段下載視頻
                if (StringUtils.hasText(rangeString)) {
                    //從Range中提取需要獲取數(shù)據(jù)的開(kāi)始和結(jié)束位置
                    long requestStart = 0, requestEnd = 0;
                    String[] ranges = rangeString.split("=");
                    if (ranges.length > 1) {
                        String[] rangeDatas = ranges[1].split("-");
                        requestStart = Integer.parseInt(rangeDatas[0]);
                        if (rangeDatas.length > 1) {
                            requestEnd = Integer.parseInt(rangeDatas[1]);
                        }
                    }
                    if (requestEnd != 0 && requestEnd > requestStart) {
                        requestSize = requestEnd - requestStart + 1;
                    }
                    //根據(jù)協(xié)議設(shè)置請(qǐng)求頭
                    response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
                    response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
                    if (!StringUtils.hasText(rangeString)) {
                        response.setHeader(HttpHeaders.CONTENT_LENGTH, fileLength + "");
                    } else {
                        long length;
                        if (requestEnd > 0) {
                            length = requestEnd - requestStart + 1;
                            response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
                            response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + requestEnd + "/" + fileLength);
                        } else {
                            length = fileLength - requestStart;
                            response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
                            response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + (fileLength - 1) + "/"
                                    + fileLength);
                        }
                    }
                    //斷點(diǎn)傳輸下載視頻返回206
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    //設(shè)置targetFile,從自定義位置開(kāi)始讀取數(shù)據(jù)
                    targetFile.seek(requestStart);
                } else {
                    //如果Range為空則下載整個(gè)視頻
                    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.mp4");
                    //設(shè)置文件長(zhǎng)度
                    response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileLength));
                }

                //從磁盤讀取數(shù)據(jù)流返回
                byte[] cache = new byte[4096];
                try {
                    while (requestSize > 0) {
                        int len = targetFile.read(cache);
                        if (requestSize < cache.length) {
                            outputStream.write(cache, 0, (int) requestSize);
                        } else {
                            outputStream.write(cache, 0, len);
                            if (len < cache.length) {
                                break;
                            }
                        }
                        requestSize -= cache.length;
                    }
                } catch (IOException e) {
                    // tomcat原話。寫操作IO異常幾乎總是由于客戶端主動(dòng)關(guān)閉連接導(dǎo)致,所以直接吃掉異常打日志
                    //比如使用video播放視頻時(shí)經(jīng)常會(huì)發(fā)送Range為0- 的范圍只是為了獲取視頻大小,之后就中斷連接了
                    log.info(e.getMessage());
                }
            } else {
                throw new RuntimeException("文件路勁有誤");
            }
            outputStream.flush();
        } catch (Exception e) {
            log.error("文件傳輸錯(cuò)誤", e);
            throw new RuntimeException("文件傳輸錯(cuò)誤");
        }finally {
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    log.error("流釋放錯(cuò)誤", e);
                }
            }
            if(targetFile != null){
                try {
                    targetFile.close();
                } catch (IOException e) {
                    log.error("文件流釋放錯(cuò)誤", e);
                }
            }
        }
    }

到了這里,關(guān)于Java后端接口返回視頻流,使用video組件播放視頻,實(shí)現(xiàn)分段下載的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 視頻推流測(cè)試——使用ffmpeg進(jìn)行推流生成rtsp視頻流

    視頻推流測(cè)試——使用ffmpeg進(jìn)行推流生成rtsp視頻流

    在我們完成開(kāi)發(fā)工作之后,需要通過(guò)推流的形式來(lái)驗(yàn)證能否正確接收視頻流,并送入視頻檢測(cè)程序。筆者在這里使用的是業(yè)內(nèi)最為常用的ffmpeg。具體方法如下。 訪問(wèn)ffmpeg的官網(wǎng),地址為https://ffmpeg.org/download.html,按照如下途中來(lái)選擇下載。 下載完成后,會(huì)得到一個(gè)zip格式的壓

    2024年02月09日
    瀏覽(41)
  • JAVA實(shí)現(xiàn)H264視頻流推送到RTSP、RTMP服務(wù)----JavaCV

    前提: 1.準(zhǔn)備好rtsp、rtmp服務(wù) 2.準(zhǔn)備好視頻流接收程序 基本思路是:?jiǎn)?dòng)兩個(gè)線程,線程1接收視頻流,線程2使用JavaCV將視頻流推送到RTSP、RTMP服務(wù),兩者之間使用管道流進(jìn)行通信。線程2接收到視頻流后的具體操作:?jiǎn)?dòng)grabber接收視頻流并捕獲視頻幀,然后啟動(dòng)recoder將捕獲的

    2024年02月11日
    瀏覽(31)
  • Windows上使用FFmpeg實(shí)現(xiàn)本地視頻推送模擬海康協(xié)議rtsp視頻流

    Windows上使用FFmpeg實(shí)現(xiàn)本地視頻推送模擬??祬f(xié)議rtsp視頻流

    Nginx搭建RTMP服務(wù)器+FFmpeg實(shí)現(xiàn)??低晹z像頭預(yù)覽: Nginx搭建RTMP服務(wù)器+FFmpeg實(shí)現(xiàn)??低晹z像頭預(yù)覽_nginx rtmp ??禂z像頭_霸道流氓氣質(zhì)的博客-CSDN博客 上面記錄的是使用FFmpeg拉取??祬f(xié)議攝像頭的rtsp流并推流到流媒體服務(wù)器。 如果在其它業(yè)務(wù)場(chǎng)景下需要本地的視頻文件模擬

    2024年02月12日
    瀏覽(22)
  • Vue中使用EasyPlayer播放H265視頻流

    Vue中使用EasyPlayer播放H265視頻流

    需要在Vue2的項(xiàng)目中使用EasyPlayer進(jìn)行H265視頻流的播放。使用官方的最新版本加載H265會(huì)有問(wèn)題。一直處于加載中… 引入easyplayer,這里最開(kāi)始引入了最新版會(huì)有問(wèn)題,因此引入的是3.3.12版本,可參照官方文檔進(jìn)行配置。 EasyPlayer示例及使用說(shuō)明 在static文件夾中引入對(duì)應(yīng)EasyPlayer.

    2024年02月03日
    瀏覽(22)
  • Vue實(shí)現(xiàn)攝像頭視頻分屏, 使用flv.js接收rtmp/flv視頻流

    Vue實(shí)現(xiàn)攝像頭視頻分屏, 使用flv.js接收rtmp/flv視頻流

    1. 現(xiàn)有的平臺(tái)系統(tǒng)播放實(shí)時(shí)視頻。 因?yàn)橛脩綦娔X都是Linux系統(tǒng),無(wú)法直接使用??登岸薙DK,討論決定由后臺(tái)推視頻流,簡(jiǎn)單調(diào)研后發(fā)現(xiàn)最流行的是flv,而且有B站開(kāi)源的flv.js適配。前期后臺(tái)推給我RTMP前綴的視頻流,我嘗試使用video.js,西瓜視頻等都失敗了,后來(lái)后端改為http前

    2024年02月03日
    瀏覽(27)
  • ZED相機(jī)使用記錄(一):利用ZED SDK使用python完成局域網(wǎng)內(nèi)的遠(yuǎn)程視頻(視頻流)傳輸

    ZED相機(jī)使用記錄(一):利用ZED SDK使用python完成局域網(wǎng)內(nèi)的遠(yuǎn)程視頻(視頻流)傳輸

    ** 本文主要介紹ZED2相機(jī)以及具有的功能,ZED2相機(jī)(這里使用ZED2相機(jī),主要是因?yàn)橐曨l流傳輸功能目前只有ZED2、ZED mini等新版本相機(jī)才有的功能)** 本文所使用的環(huán)境: python:3.8 CUDA:10.2 需要安裝的python庫(kù):pyzed(安裝好ZED SDK后安裝)、opencv(cv2)、sys 接收端(服務(wù)端):測(cè)試過(guò)的有

    2024年02月13日
    瀏覽(139)
  • 使用Flask+OpenCV實(shí)現(xiàn)瀏覽器/微信小程序的視頻流傳輸

    前言 一、 Flask+瀏覽器實(shí)現(xiàn) 二、 Flask+微信小程序?qū)崿F(xiàn) 三、Flask+uni-app小程序?qū)崿F(xiàn) 后記 近期在做的東西涉及到實(shí)時(shí)視頻的處理,碰到一些問(wèn)題,因此將之記錄下來(lái),便于日后翻看,同時(shí)也希望能給遇到同樣問(wèn)題的小伙伴提供幫助。 實(shí)現(xiàn)代碼如下: 分為 app.py 和index.html。 1. F

    2024年02月06日
    瀏覽(167)
  • VS+QT+Opencv使用YOLOv4對(duì)視頻流進(jìn)行目標(biāo)檢測(cè)

    對(duì)單張圖像的檢測(cè),請(qǐng)參考:https://blog.csdn.net/qq_45445740/article/details/109659938

    2024年02月12日
    瀏覽(92)
  • vue2使用rtsp視頻流接入??低晹z像頭(純前端)

    vue2使用rtsp視頻流接入海康威視攝像頭(純前端)

    ??低暪俜降腞TSP最新取流格式如下: rtsp://用戶名:密碼@IP:554/Streaming/Channels/101 用戶名和密碼 IP就是登陸攝像頭時(shí)候的IP(筆者這里IP是192.168.1.210) 所以筆者的rtsp流地址就是 rtsp://用戶名:密碼@192.168.1.210:554/Streaming/Channels/101 1.1關(guān)閉 螢石云的接入 1.2 調(diào)整視頻編碼為H.264 在此下載

    2024年04月26日
    瀏覽(25)
  • vue使用vue-h265-player播放h265編碼格式視頻流

    vue使用vue-h265-player播放h265編碼格式視頻流

    GitHub地址 vue-h265-player 支持h265編碼格式視頻流播放 vue使用vue-h265-player 1、安裝vue-h265-player 2、拷貝libDecoder.wasm文件到public目錄下 復(fù)制node_modules/h265-player/lib/libDecoder.wasm文件到public目錄下 3、示例代碼 url: 需要播放的鏈接,播放器會(huì)根據(jù)該值的變化自動(dòng)重啟。 maxRetryCount: 最大嘗

    2024年02月14日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包