javaCV 視頻工具—截取視頻縮略圖、獲取視頻屬性


@

目錄

簡介

通過javaCV 視頻工具—截取視頻縮略圖、獲取視頻屬性

依賴引入

<!--javaCV 視頻工具-->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5</version>
        </dependency>

實現

@Slf4j
public class VideoUtils {

    private static final String IMAGEMAT = "png";
    private static final String ROTATE = "rotate";

    /**
     * 默認截取視頻的中間幀為封面
     */
    public static final int MOD = 2;

    /**
     * 視頻縮略圖后綴
     */
    private static final String VIDEO_THUMBNAIL_SUF = "th.png";

    /**
     * 視頻縮略圖前綴
     */
    private static final String VIDEO_THUMBNAIL_PRE = "video/thumbnail/";

    private static final String SYMBOL = ".";

    /**
     * 獲取視頻縮略圖
     * @param filePath:視頻路徑
     * @param mod:視頻長度/mod獲取第幾幀
     * @throws Exception
     */
    public static String randomGrabberFFmpegImage(String filePath, int mod) {
        String targetFilePath = "";
        try{
            FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
            ff.start();
            //圖片位置是否正確
            String rotate = ff.getVideoMetadata(ROTATE);
            //獲取幀數
            int ffLength = ff.getLengthInFrames();
            Frame f;
            int i = 0;
            //設置截取幀數
            int index = ffLength / mod;
            while (i < ffLength) {
                f = ff.grabImage();
                if(i == index){
                    if (null != rotate && rotate.length() > 1) {
                        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
                        IplImage src = converter.convert(f);
                        f = converter.convert(rotate(src, Integer.parseInt(rotate)));
                    }
                    targetFilePath = getImagePath(filePath, i);
                    doExecuteFrame(f, targetFilePath);
                    break;
                }
                i++;
            }
            ff.stop();
        }catch (Exception e){
            log.error("獲取視頻縮略圖異常:" + e.getMessage());
        }
        return targetFilePath;
    }

    /**
     * 隨機生成生成縮略圖存放路徑
     * @param filePath:視頻路徑
     * @param index:第幾幀
     * @return:縮略圖的存放路徑
     */
    private static String getImagePath(String filePath, int index){
        String fileName = FileUtils.getName(filePath);
        //去后綴
        fileName = fileName.substring(0, fileName.indexOf(SYMBOL));
        return TencentCosConfig.baseUrl + VIDEO_THUMBNAIL_PRE + DateUtils.datePath() + "/" + fileName + "_" + index +  VIDEO_THUMBNAIL_SUF;
    }

    /**
     * 旋轉圖片
     * @param src
     * @param angle
     * @return
     */
    public static IplImage rotate(IplImage src, int angle) {
        IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
        opencv_core.cvTranspose(src, img);
        opencv_core.cvFlip(img, img, angle);
        return img;
    }

    /**
     * 截取縮略圖
     * @param f
     * @param targerFilePath:封面圖片
     */
    public static void doExecuteFrame(Frame f, String targerFilePath) {
        COSClient cosClient = TencentCosUtils.initCosClient();

        if (null == f || null == f.image) {
            return;
        }
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bi = converter.getBufferedImage(f);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(bi, IMAGEMAT, out);
            // 獲取文件流
            InputStream bufferedImage = new ByteArrayInputStream(out.toByteArray());
            int length = out.size();
            ObjectMetadata objectMetadata = new ObjectMetadata();
            // 從輸入流上傳必須制定content length, 否則http客戶端可能會緩存所有數據,存在內存OOM的情況
            objectMetadata.setContentLength(length);
            // 默認下載時根據cos路徑key的后綴返回響應的contenttype, 上傳時設置contenttype會覆蓋默認值
            PutObjectRequest putObjectRequest = new PutObjectRequest(TencentCosConfig.bucket, targerFilePath, bufferedImage, objectMetadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            log.info("騰訊COS上傳視頻縮略圖成功:{}", putObjectResult.getETag());
            //關閉輸入輸出流
            bufferedImage.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            cosClient.shutdown();
        }
    }

    /**
     * 根據視頻長度隨機生成隨機數集合
     * @param baseNum:基礎數字,此處為視頻長度
     * @param length:隨機數集合長度
     * @return:隨機數集合
     */
    public static List<Integer> random(int baseNum, int length) {
        List<Integer> list = new ArrayList<Integer>(length);
        while (list.size() < length) {
            Integer next = (int) (Math.random() * baseNum);
            if (list.contains(next)) {
                continue;
            }
            list.add(next);
        }
        Collections.sort(list);
        return list;
    }

    /**
     * 獲取視頻時長 單位/秒
     * @param video
     * @return
     */
    public static long getVideoDuration(File video) {
        long duration = 0L;
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
        try {
            ff.start();
            duration = ff.getLengthInTime() / (1000 * 1000);
            ff.stop();
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
        return duration;
    }

    /**
     * 獲取視頻時長 單位/秒
     * @param inputStream 輸入流
     * @return
     */
    public static long getVideoDuration(InputStream inputStream) {
        long duration = 0L;
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(inputStream);
        try {
            ff.start();
            duration = ff.getLengthInTime() / (1000 * 1000);
            ff.stop();
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
        return duration;
    }

    /**
     * 轉換視頻文件為mp4
     * @param file
     * @return
     */
    public static String convertToMp4(File file) {
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
        String fileName = null;
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;

        try {
            frameGrabber.start();
            fileName = file.getAbsolutePath() + "__.mp4";
            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 (FrameRecorder.Exception e) {
                    e.printStackTrace();
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
        } catch (Exception | FrameRecorder.Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM