gpt4 book ai didi

苹果手机H5video标签播放视频问题以及.mov格式处理方案

转载 作者:我是一只小鸟 更新时间:2023-03-08 14:31:22 31 4
gpt4 key购买 nike

最近在做一个手机端拍照上传,并预览文件的功能,前端用h5 video 标签,后端用springboot+minio.

问题

刚开始写代码和测试的时候,都是用的安卓手机,照片和视频都没问题,后来换成用苹果手机后,播放视频就出现各种问题,先是苹果手机拍的mov视频不支持播放,后面又出现苹果手机播放不了视频,应该是ios浏览器不兼容video标签.

后来网上找了半天,终于找到了解决方案.

解决方案

iOS上播放视频,http协议中应用rang请求头.

视频格式MP4是正确的,但是你的后台没有对ios的视频播放器做适配。如果想要在iOS上播放视频,那么必须在http协议中应用rang请求头。 对于有的朋友还对ios播放器http的range标记不是很懂。我再讲解下.

视频文件总长度是123456789 range是播放器要求的区间也就是客户端发送请求的时候http会带有这个标记,这个区间的值在http.headers.range中获取,一般是bytes=0-1这样的.

我们需要做的处理是返回文件的指定区间(如上面的例子,我们就应该返回0到1的字符),并添加Content-Range:btyes 0-1、Accept-Ranges:bytes、'Content-Length: 123456789','Content-Type: video/mp4'到http.headers中 。

代码

下面是前后端代码,上传就用的minio sdk上传的,这个代码就不贴了.

前端

                          
                            <!
                          
                          
                            -webkit-playsinline="true"/*这个属性是ios 10中设置可以让视频在小窗内播放,即不全屏播放*/
playsinline="true"/*I0s微信浏览器支持小窗内播放*/
x-webkit-airplay="allow"/*使此视频支持ios的AirPlay功能*/
x5-video-player-type="h5”/*启用H5播放器,是wechat?安卓版特性*/
x5-video-player-fullscreen="true”/*全屏设置,设置为true是防止横屏*/
                          
                          
                            >
                          
                          
                            
-->

                          
                          
                            <
                          
                          
                            video
    
                          
                          
                            autoplay
    class
                          
                          
                            ="video"
                          
                          
                            
    v-if
                          
                          
                            ="urlType === 'video'"
                          
                          
                            
    :src
                          
                          
                            ="previewUrl"
                          
                          
                            
    controls
    type
                          
                          
                            ="video/mp4"
                          
                          
                            
    webkit-playsinline
                          
                          
                            ="true"
                          
                          
                            
    playsinline
                          
                          
                            ="true"
                          
                          
                            
    x5-playsinline
                          
                          
                            ="true"
                          
                          
                            
    x-webkit-airplay
                          
                          
                            ="allow"
                          
                          
                            
    x5-video-player-fullscreen
                          
                          
                            ="true"
                          
                          
                            
    x5-video-player-type
                          
                          
                            ="h5"
                          
                          
                            ></
                          
                          
                            video
                          
                          
                            >
                          
                        

后端

                          
                            /**
 * 分段下载
 *
 * @param bucket
 * @param fileName
 * @param response
 */
@GetMapping("file/range/{bucket}/{fileName}")
public void fileRangeIgnoreToken(@PathVariable String bucket, @PathVariable String fileName, HttpServletRequest request, HttpServletResponse response) {
    String property = System.getProperty("user.dir");
    String filePath = property + "/" + fileName;
    log.info("新生文件的路径:{}", filePath);
    File file = new File(filePath);

    InputStream inputStream = minioTemplate.getObject(bucket, fileName);

    try {
        FileUtils.copyInputStreamToFile(inputStream, file);
        this.rangeVideo(request, response, file, fileName);
    } catch (Exception e) {
        e.printStackTrace();
        log.error("分段发送文件出错,失败原因:{}", Throwables.getStackTraceAsString(e));
    } finally {
        FileUtil.del(file);
    }
}

/**
 * 新增视频加载方法,解决ios系统vedio标签无法播放视频问题
 *
 * @param request
 * @param response
 * @param file
 * @param fileName
 * @throws FileNotFoundException
 * @throws IOException
 */
public void rangeVideo(HttpServletRequest request, HttpServletResponse response, File file, String fileName) throws FileNotFoundException, IOException {
    RandomAccessFile randomFile = new RandomAccessFile(file, "r");//只读模式
    long contentLength = randomFile.length();
    log.info("获取导的contentLength={}", contentLength);
    String range = request.getHeader("Range");
    int start = 0, end = 0;
    if (range != null && range.startsWith("bytes=")) {
        String[] values = range.split("=")[1].split("-");
        start = Integer.parseInt(values[0]);
        if (values.length > 1) {
            end = Integer.parseInt(values[1]);
        }
    }
    int requestSize = 0;
    if (end != 0 && end > start) {
        requestSize = end - start + 1;
    } else {
        requestSize = Integer.MAX_VALUE;
    }

    response.setContentType("video/mp4");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", fileName);
    response.setHeader("Last-Modified", new Date().toString());
    //第一次请求只返回content length来让客户端请求多次实际数据
    if (range == null) {
        response.setHeader("Content-length", contentLength + "");
    } else {
        //以后的多次以断点续传的方式来返回视频数据
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206
        long requestStart = 0, requestEnd = 0;
        String[] ranges = range.split("=");
        if (ranges.length > 1) {
            String[] rangeDatas = ranges[1].split("-");
            requestStart = Integer.parseInt(rangeDatas[0]);
            if (rangeDatas.length > 1) {
                requestEnd = Integer.parseInt(rangeDatas[1]);
            }
        }
        long length = 0;
        if (requestEnd > 0) {
            length = requestEnd - requestStart + 1;
            response.setHeader("Content-length", "" + length);
            response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
        } else {
            length = contentLength - requestStart;
            response.setHeader("Content-length", "" + length);
            response.setHeader("Content-Range", "bytes " + requestStart + "-" + (contentLength - 1) + "/" + contentLength);
        }
    }
    ServletOutputStream out = response.getOutputStream();
    int needSize = requestSize;
    randomFile.seek(start);
    while (needSize > 0) {
        byte[] buffer = new byte[4096];
        int len = randomFile.read(buffer);
        if (needSize 
                          
                          
                            <
                          
                          
                             buffer
                          
                          
                            .length) {
            out.write(buffer, 0, needSize);
        } else {
            out.write(buffer, 0, len);
            if (len < buffer.length) {
                break;
            }
        }
        needSize -
                          
                          
                            = buffer.length;
    
                          
                          
                            }
    randomFile.close();
    out.close();
}
                          
                        

上面这段代码可以解决本文开头提到的两个问题.

补充:.mov视频播放不了怎么解决?

还有一种思路,也是我一开始的做法,就是先从文件服务器上读取视频文件,然后在后台强制把.mov转成.mp4输出.

代码也贴下 。

                          @GetMapping("file/{bucket}/{fileName}"
                          
                            )
@IgnoreUserToken
@IgnoreClientToken

                          
                          
                            public
                          
                          
                            void
                          
                          
                             fileIgnoreToken(@PathVariable String bucket, @PathVariable String fileName, HttpServletResponse response) {
    
                          
                          
                            if
                          
                           (fileName.toLowerCase().contains(".mov"
                          
                            )) {
        log.info(
                          
                          "进入mov文件转码"
                          
                            );
        File source 
                          
                          = 
                          
                            null
                          
                          
                            ;
        File target 
                          
                          = 
                          
                            null
                          
                          
                            ;
        
                          
                          
                            try
                          
                          
                             {
            InputStream inputStream 
                          
                          =
                          
                             minioTemplate.getObject(bucket, fileName);
            source 
                          
                          = 
                          
                            new
                          
                           File("/" + IdUtil.simpleUUID() + ".mov"
                          
                            );
            target 
                          
                          = 
                          
                            new
                          
                           File("/" + IdUtil.simpleUUID() + ".mp4"
                          
                            );
            FileUtils.copyInputStreamToFile(inputStream, source);

            AudioAttributes audio 
                          
                          = 
                          
                            new
                          
                          
                             AudioAttributes();
            audio.setCodec(
                          
                          "libmp3lame"
                          
                            );
            audio.setBitRate(
                          
                          
                            new
                          
                           Integer(800000));
                          
                            //
                          
                          
                            设置比特率
                          
                          
            audio.setChannels(
                          
                            new
                          
                           Integer(1));
                          
                            //
                          
                          
                            设置音频通道数
                          
                          
            audio.setSamplingRate(
                          
                            new
                          
                           Integer(44100));
                          
                            //
                          
                          
                            设置采样率
                          
                          
            VideoAttributes video = 
                          
                            new
                          
                          
                             VideoAttributes();

                          
                          
                            //
                          
                          
                                        video.setCodec("mpeg4");
                          
                          
            video.setCodec("libx264"
                          
                            );
            video.setBitRate(
                          
                          
                            new
                          
                           Integer(3200000
                          
                            ));
            video.setFrameRate(
                          
                          
                            new
                          
                           Integer(15
                          
                            ));
            EncodingAttributes attrs 
                          
                          = 
                          
                            new
                          
                          
                             EncodingAttributes();
            attrs.setOutputFormat(
                          
                          "mp4"
                          
                            );
            attrs.setAudioAttributes(audio);
            attrs.setVideoAttributes(video);
            Encoder encoder 
                          
                          = 
                          
                            new
                          
                          
                             Encoder();
            encoder.encode(
                          
                          
                            new
                          
                          
                             MultimediaObject(source), target, attrs);
            IoUtil.copy(
                          
                          
                            new
                          
                          
                             FileInputStream(target), response.getOutputStream());
        } 
                          
                          
                            catch
                          
                          
                             (Exception e) {
            log.error(
                          
                          "转码文件出错,失败原因:{}"
                          
                            , Throwables.getStackTraceAsString(e));
        } 
                          
                          
                            finally
                          
                          
                             {
            log.info(
                          
                          "删除临时文件"
                          
                            );
            FileUtil.del(source);
            FileUtil.del(target);
        }
    } 
                          
                          
                            else
                          
                          
                             {
        
                          
                          
                            try
                          
                          
                             {
            IoUtil.copy(minioTemplate.getObject(bucket, fileName), response.getOutputStream());
        } 
                          
                          
                            catch
                          
                          
                             (IOException e) {
            log.error(
                          
                          "读取文件出错,失败原因:{}"
                          
                            , Throwables.getStackTraceAsString(e));
        }
    }
}
                          
                        

  。

最后此篇关于苹果手机H5video标签播放视频问题以及.mov格式处理方案的文章就讲到这里了,如果你想了解更多关于苹果手机H5video标签播放视频问题以及.mov格式处理方案的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com