Java實現視頻截圖和視頻轉碼功能

之前一直想找一份可以實現Java操作視頻文件的代碼,找了很久,看到網上的都是很離散的一些功能實現,所以現在收集並整理了具體的功能實現,具體如下代碼:

maven依賴:

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.5</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.5</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>4.0.1-1.4.4</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.1-1.4.4</version>
        </dependency>

具體的實現工具類如下:

/**
 * @author zhq.xiang
 */
public class VedioUtils {
    /**
     * 截取視頻的第一幀圖片
     *
     * @param videoFile 可以用 inputStream 代替
     * @param outputStream
     */
    public static void fetchFrame(File videoFile, OutputStream outputStream, String outFormatName) {
        FFmpegFrameGrabber ff = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(videoFile);
            ff = new FFmpegFrameGrabber(fis);
            ff.start();
            int length = ff.getLengthInFrames();
            int i = 0;
            Frame frame = null;
            while (i < length) {
                // 過濾前5幀,避免出現全黑的圖片,依自己情況而定
                frame = ff.grabFrame();
                if ((i > 5) && (frame.image != null)) {
                    break;
                }
                i++;
            }
            Java2DFrameConverter converter = new Java2DFrameConverter();
            BufferedImage bi = converter.getBufferedImage(frame);
            ImageIO.write(bi, outFormatName, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                if (ff != null) {
                    ff.stop();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 獲取視頻時長 單位/秒
     *
     * @param video 可以用inputStream代替
     * @return
     */
    public static long getVideoDuration(File video) {
        long duration = 0L;
        FFmpegFrameGrabber ff = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(video);
            ff = new FFmpegFrameGrabber(fis);
            ff.start();
            duration = ff.getLengthInTime() / (1000 * 1000);
            return duration;
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ff != null){
                try {
                    ff.stop();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return 0L;
    }


    /**
     * 轉換視頻文件爲mp4
     *
     * @param file 可以用inputStream代替
     * @return
     */
    public static String convert2Mp4(File file) {
        FFmpegFrameGrabber frameGrabber = null;
        Frame capturedFrame = null;
        FFmpegFrameRecorder recorder = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            frameGrabber = new FFmpegFrameGrabber(fis);
            frameGrabber.start();
            String fileName = file.getAbsolutePath() + "__.mp4";
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(),
                frameGrabber.getAudioChannels());
            //avcodec.AV_CODEC_ID_H264 清晰度較低 //AV_CODEC_ID_MPEG4 清晰度更高
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setSampleRate(frameGrabber.getSampleRate());

            recorder.setAudioChannels(frameGrabber.getAudioChannels());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.start();
            while ((capturedFrame = frameGrabber.grabFrame()) != null) {
                recorder.setTimestamp(frameGrabber.getTimestamp());
                recorder.record(capturedFrame);
            }

            return fileName;
        } catch (Exception e) {
            e.printStackTrace();
        } catch (FrameRecorder.Exception e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(recorder != null) {
                try {
                    recorder.stop();
                    recorder.release();
                } catch (FrameRecorder.Exception e) {
                    e.printStackTrace();
                }
            }
            if(frameGrabber != null) {
                try {
                    frameGrabber.stop();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    public static void main(String[] args) {
        File file = new File("/Users/xiangzhongqiang/Downloads/hailuo_20783575_RF.mov");
        String destPath = "/Users/xiangzhongqiang/Downloads/1111.jpg";
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(destPath);
            fetchFrame(file, fos,
                destPath.substring(destPath.indexOf(Constants.SYMBOL_DOT)).replaceAll("\\" + Constants.SYMBOL_DOT, ""));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        convert2Mp4(file);

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章