kkFileview(十三)——视频图片处理

2021SC@SDUSC

        对视频文件的处理封装在类MediaFilePreviewImpl中,包含filePreviewHandle文件预览处理、convertUrl检查视频文件处理逻辑、checkNeedConvert检查是否需要转换、convertToMp4遇到浏览器无法处理的视频格式时将视频格式转换为MP4。

目录

1、文件预览处理

2、处理视频文件

 3、将不兼容格式转换成MP4

4、检查视频文件是否需要转换 


1、文件预览处理

        首先根据url判断文件是不是浏览器可以直接访问的(是http开头),若不是则调用DownloadUtils工具类中的downLoad方法将文件下载到本地,之后调用BaseUrlFilter工具类的getBaseUrl() 方法和fileHandlerService的getRelativePath方法获取下载后的url,并赋给fileAttribute文件属性对象方便日后调用。

        之后调用类中的checkNeedConvert方法检查文件是否需要转换,若需要则调用convertUrl检查视频逻辑并返回处理后的url。若是正常的视频类型,说明不需要转换,调用ConfigConstants的getMedia()方法获取视频类型。

        进入for循环,通过判断文件属性后缀media.equals(fileAttribute.getSuffix())来判断文件是否系统可以处理的视频类型,并返回 MEDIA_FILE_PREVIEW_PAGE,若循环结束后都不存在匹配,则返回“暂不支持该文件类型”。

    @Override
    public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
        // 不是http开头,浏览器不能直接访问,需下载到本地
        if (url != null && !url.toLowerCase().startsWith("http")) {
            ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
            if (response.isFailure()) {
                return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
            } else {
                url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent());
                fileAttribute.setUrl(url);
            }
        }

        if(checkNeedConvert(fileAttribute.getSuffix())){
            url=convertUrl(fileAttribute);
        }else{
            //正常media类型
            String[] medias = ConfigConstants.getMedia();
            for(String media:medias){
                if(media.equals(fileAttribute.getSuffix())){
                    model.addAttribute("mediaUrl", url);
                    return MEDIA_FILE_PREVIEW_PAGE;
                }
            }
            return otherFilePreview.notSupportedFile(model, fileAttribute, "暂不支持");
        }
        model.addAttribute("mediaUrl", url);
        return MEDIA_FILE_PREVIEW_PAGE;
    }

2、处理视频文件

首先判断系统可以转换的文件中是否包含该文件类型,若包含则根据url直接转换,若不包含则调用convertToMp4(fileAttribute)方法将该文件加入缓存之后再调用 fileHandlerService的addConvertedMedias(url,convertedUrl)将文件加入浏览列表中,最后返还转换过后的url。

    /**
     * 检查视频文件处理逻辑
     * 返回处理过后的url
     * @return url
     */
    private String convertUrl(FileAttribute fileAttribute) {
        String url = fileAttribute.getUrl();
        if(fileHandlerService.listConvertedMedias().containsKey(url)){
            url= fileHandlerService.getConvertedMedias(url);
        }else{
            if(!fileHandlerService.listConvertedMedias().containsKey(url)){
                synchronized(LOCK){
                    if(!fileHandlerService.listConvertedMedias().containsKey(url)){
                        String convertedUrl=convertToMp4(fileAttribute);
                        //加入缓存
                        fileHandlerService.addConvertedMedias(url,convertedUrl);
                        url=convertedUrl;
                    }
                }
            }
        }
        return url;
    }

 3、将不兼容格式转换成MP4

    /**
     * 将浏览器不兼容视频格式转换成MP4
     * @param fileAttribute
     * @return
     */
    private static String convertToMp4(FileAttribute fileAttribute) {

        //说明:这里做临时处理,取上传文件的目录
        String homePath = ConfigUtils.getHomePath();
        String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
        String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");

        File file=new File(filePath);
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
        String fileName = null;
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;
        try {
            fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
            File desFile=new File(fileName);
            //判断一下防止穿透缓存
            if(desFile.exists()){
                return fileName;
            }

            frameGrabber.start();
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            //recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
            recorder.setSampleRate(frameGrabber.getSampleRate());

            recorder.setAudioChannels(frameGrabber.getAudioChannels());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.start();
            while ((captured_frame = frameGrabber.grabFrame()) != null) {
                try {
                    recorder.setTimestamp(frameGrabber.getTimestamp());
                    recorder.record(captured_frame);
                } catch (Exception e) {
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //是否删除源文件
        //file.delete();
        return convertFileName;
    }

4、检查视频文件是否需要转换 

    /**
     * 检查视频文件转换是否已开启,以及当前文件是否需要转换
     * @return
     */
    private boolean checkNeedConvert(String suffix) {
        //1.检查开关是否开启
        if("false".equals(ConfigConstants.getMediaConvertDisable())){
            return false;
        }
        //2.检查当前文件是否需要转换
        String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
        String type = suffix;
        for(String temp : mediaTypesConvert){
            if(type.equals(temp)){
                return true;
            }
        }
        return false;
    }

 


版权声明:本文为m0_55503427原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。