解决h5中video标签返回流无法快进和后退的问题

private void play(File downloadFile ,HttpServletRequest request, 
					HttpServletResponse response ){
        try {
            if (!downloadFile.exists()) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                return;
            }

            long fileLength = downloadFile.length();// 记录文件大小
            long pastLength = 0;// 记录已下载文件大小
            int rangeSwitch = 0;// 0:从头开始的全文下载;1:从某字节开始的下载(bytes=27000-);2:从某字节开始到某字节结束的下载(bytes=27000-39000)
            long contentLength = 0;// 客户端请求的字节总量
            String rangeBytes = "";// 记录客户端传来的形如“bytes=27000-”或者“bytes=27000-39000”的内容
            RandomAccessFile raf = null;// 负责读取数据
            OutputStream os = null;// 写出数据
            OutputStream out = null;// 缓冲
            int bsize = 1024;// 缓冲区大小
            byte b[] = new byte[bsize];// 暂存容器

            String range = request.getHeader("Range");
            int responseStatus = 206;
            if (range != null && range.trim().length() > 0 && !"null".equals(range)) {// 客户端请求的下载的文件块的开始字节
                responseStatus = javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT;
                System.out.println("request.getHeader(\"Range\")=" + range);
                rangeBytes = range.replaceAll("bytes=", "");
                if (rangeBytes.endsWith("-")) {
                    rangeSwitch = 1;
                    rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf('-'));
                    pastLength = Long.parseLong(rangeBytes.trim());
                    contentLength = fileLength - pastLength;
                } else {
                    rangeSwitch = 2;
                    String temp0 = rangeBytes.substring(0, rangeBytes.indexOf('-'));
                    String temp2 = rangeBytes.substring(rangeBytes.indexOf('-') + 1, rangeBytes.length());
                    pastLength = Long.parseLong(temp0.trim());
                }
            } else {
                contentLength = fileLength;// 客户端要求全文下载
            }

            // 清除首部的空白行
            response.reset();
            // 告诉客户端允许断点续传多线程连接下载,响应的格式是:Accept-Ranges: bytes
            response.setHeader("Accept-Ranges", "bytes");
            // 如果是第一次下,还没有断点续传,状态是默认的 200,无需显式设置;响应的格式是:HTTP/1.1

            if (rangeSwitch != 0) {
                response.setStatus(responseStatus);
                // 不是从最开始下载,断点下载响应号为206
                // 响应的格式是:
                // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
                switch (rangeSwitch) {
                    case 1: {
                        String contentRange = new StringBuffer("bytes ")
                                .append(new Long(pastLength).toString()).append("-")
                                .append(new Long(fileLength - 1).toString())
                                .append("/").append(new Long(fileLength).toString())
                                .toString();
                        response.setHeader("Content-Range", contentRange);
                        break;
                    }
                    case 2: {
                        String contentRange = range.replace("=", " ") + "/"
                                + new Long(fileLength).toString();
                        response.setHeader("Content-Range", contentRange);
                        break;
                    }
                    default: {
                        break;
                    }
                }
            } else {
                String contentRange = new StringBuffer("bytes ").append("0-")
                        .append(fileLength - 1).append("/").append(fileLength)
                        .toString();
                response.setHeader("Content-Range", contentRange);
            }
            response.setContentType("video/mp4;charset=UTF-8");
            response.setHeader("Content-Length", String.valueOf(contentLength));
            os = response.getOutputStream();
            out = new BufferedOutputStream(os);
            raf = new RandomAccessFile(downloadFile, "r");
            try {
                long outLength = 0;// 实际输出字节数
                switch (rangeSwitch) {
                    case 0: {
                    }
                    case 1: {
                        raf.seek(pastLength);
                        int n = 0;
                        while ((n = raf.read(b)) != -1) {
                            out.write(b, 0, n);
                            outLength += n;
                        }
                        break;
                    }
                    case 2: {
                        raf.seek(pastLength);
                        int n = 0;
                        long readLength = 0;// 记录已读字节数
                        while (readLength <= contentLength - bsize) {// 大部分字节在这里读取
                            n = raf.read(b);
                            readLength += n;
                            out.write(b, 0, n);
                            outLength += n;
                        }
                        if (readLength <= contentLength) {// 余下的不足 1024 个字节在这里读取
                            n = raf.read(b, 0, (int) (contentLength - readLength));
                            out.write(b, 0, n);
                            outLength += n;
                        }
                        break;
                    }
                    default: {
                        break;
                    }
                }
                System.out.println("Content-Length为:" + contentLength + ";实际输出字节数:" + outLength);
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (raf != null) {
                    try {
                        raf.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: h5 video不显示进度条一般是因为视频播放器的控制条被隐藏了,可以在播放器的属性设置控制条的显示与隐藏。至于不能快进问题,可能是因为视频的编码格式或者播放器的设置问题导致的。如果是编码格式的问题,可以尝试转换视频格式或者使用优秀的编码软件重新编码视频;如果是播放器的设置问题,可以查看播放器相关的API文档和使用说明,进行相应的设置调整,以解决快进功能无法使用的问题。此外,还可以考虑使用第三方开源的视频播放器插件,例如video.js、jwplayer等,这些插件不仅可以解决视频播放问题,还可以提供更多的功能和美化效果,提升用户体验。总之,h5 video不显示进度条不能快进要仔细分析问题原因,并采取相应的解决措施。 ### 回答2: H5 video 是基于 HTML5 技术开发的视频播放器,由于其良好的兼容性和支持性,已经成为当前主的网页视频播放方式。然而,有候我们可能会遇到 H5 video 不显示进度条、不能快进问题,这主要有以下原因: 1.视频格式问题H5 video 对一些视频格式的支持性可能存在限制,如果所播放的视频格式不支持,则会导致视频进度条无法显示,无法进行快进等操作。 2.音视频文件不完整或损坏:如果所播放的音视频文件不完整或损坏,可能会导致视频进度条无法显示,无法进行快进等操作。 3.缓存问题:有候我们可能会在播放过程遇到视频进度条无法显示、无法快进的情况,这可能是由于缓存未完全加载导致的。可以尝试清除浏览器缓存或重新加载页面解决。 针对以上问题,我们可以采取以下解决措施: 1.检查视频格式:确认所要播放的视频格式是否被 H5 video 支持,如果不支持,可以考虑使用其他格式或转换工具将视频转成支持格式。 2.检查音视频文件完整性:确认所要播放的音视频文件是否完整,并且未损坏。如果文件不完整或损坏,可以重新下载或使用修复工具修复文件。 3.清除浏览器缓存:在遇到视频进度条无法显示、无法快进问题,可以尝试清除浏览器缓存,重新加载视频页面。 除此之外,为了提高 H5 video播放过程的体验,我们也可以采用以下建议: 1.视频预加载:在加载页面预先加载视频文件,以保证视频缓存完全。 2.网络优化:优化网络连接,提高视频下载速度,避免视频卡顿或加载缓慢的情况。 3.增加交互体验:可以添加交互组件,如暂停、快进、倒退、全屏等功能,以提高用户体验。 ### 回答3: 近年来,随着移动互联网的迅速发展,H5视频作为一种使用方便、便于传播的视频播放方式逐渐受到更多人的喜爱。然而,在使用H5视频,有会遇到一些问题,比如无法显示进度条,不能快进问题。这些问题可能会给用户带来不便和困扰。 首先,对于H5视频无法显示进度条的问题,我们可以尝试检查以下几个方面。首先,我们要确定视频的格式是否与浏览器兼容。如果视频格式不被浏览器支持,那么就会出现无法显示进度条的情况。要解决这个问题,我们要在编码视频的候,选择浏览器支持的格式进行编码,或者通过引入第三方库进行视频格式兼容的处理。 其次,我们还要检查是否要设置视频的属性。有些H5视频播放要对视频属性进行设置,以便正确地显示进度条。要设置的属性包括视频的宽度、高度、播放长、总长等。正确地设置这些属性可以确保视频播放进度条的显示正常。 最后,对于H5视频不能快进问题,我们要检查视频源文件是否正常。如果视频源文件损坏或者遗失某些数据,那么就会影响到视频的正常播放快进。此,我们要重新获取或修复视频源文件,以便确保视频播放正常。 除了上述几点,还有一些其它的问题可能会导致H5视频无法显示进度条或不能快进。比如网络状况不佳,服务器响应慢等等。针对这些问题,我们要进一步深入定位问题,并采取相应的修复措施。 总之,H5视频作为一种现代化的视频播放方式,不仅使用方便,而且便于传播,可以满足人们在移动设备上观看视频的求。但是在使用过程会遇到一些问题,我们要积极解决这些问题,以便更好地使用H5视频。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值