国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java實現(xiàn)截取視頻第一幀

這篇具有很好參考價值的文章主要介紹了Java實現(xiàn)截取視頻第一幀。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

前言

一、通過Java借助第三方庫實現(xiàn)

1.引用ffmpeg

使用maven,導入pom依賴:

?工具類

2.引用jcodec

二、使用第三方存儲自帶的方法實現(xiàn)(如阿里云OSS、華為云OBS)


前言

在實際項目中,會遇到上傳視頻后,需要截取視頻的首幀或指定幀為圖片,作為展示使用的需求。這個需求本身并不難,而且網(wǎng)上一搜一大把,今天就針對網(wǎng)上的部分方法做個總結。


一、通過Java借助第三方庫實現(xiàn)

1.引用ffmpeg

  • 使用maven,導入pom依賴:

        <!-- 操作視頻流 -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>


  • ?工具類

import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;

/**
 * 視頻操作工具類
 */
@Slf4j
public class VideoUtils {

    /**
     * 截取視頻第一幀為圖片展示
     *
     * @param filePath       視頻路徑
     * @param targetFilePath 第一幀圖片存儲位置
     * @param targetFileName 圖片名稱
     */
    public static void getVideoFirstFrameImage(String filePath, String targetFilePath, String targetFileName) throws Exception {
        FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
        ff.start();
        String rotate = ff.getVideoMetadata("rotate");
        Frame f;
        int i = 0;
        while (i < 1) {
            f = ff.grabImage();
            IplImage src;
            if (null != rotate && rotate.length() > 1) {
                OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
                src = converter.convert(f);
                f = converter.convert(rotate(src, Integer.parseInt(rotate)));
            }
            doExecuteFrame(f, targetFilePath, targetFileName);
            i++;
        }
        ff.stop();
    }

    /**
     * 進行旋轉角度操作(為了保證截取到的第一幀圖片與視頻中的角度方向保持一致)
     */
    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;
    }

    public static void doExecuteFrame(Frame f, String targetFilePath, String targetFileName) {
        if (null == f || null == f.image) {
            return;
        }
        Java2DFrameConverter converter = new Java2DFrameConverter();
        String imageMat = "jpg";
        String fileName = targetFilePath + File.separator + targetFileName + "." + imageMat;
        BufferedImage bi = converter.getBufferedImage(f);
        File output = new File(fileName);
        try {
            ImageIO.write(bi, imageMat, output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        String url = "C:\\Users\\admin\\Desktop\\test.mp4";
        getVideoFirstFrameImage(url, "C:\\Users\\admin\\Desktop", "first");
    }

}


2.引用jcodec

????????網(wǎng)上視頻截取第一幀的案例還是比較多的,普遍的方法主要是使用ffmpeg對其截取。在實踐過程中,發(fā)現(xiàn)在自己本地或在window上截取都是成功的。但在Linux 環(huán)境中截取失敗,這里將失敗內容貼出來,供他人查看失敗原因

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x000000000000d1f6, pid=14, tid=0x00007fe8b67e6b10
#
# JRE version: OpenJDK Runtime Environment (8.0_212-b04) (build 1.8.0_212-b04)
# Java VM: OpenJDK 64-Bit Server VM (25.212-b04 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 3.12.0
# Distribution: Custom build (Sat May  4 17:33:35 UTC 2019)
# Problematic frame:
# C  0x000000000000d1f6
#
# Core dump written. Default location: //core or core.14
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   https://icedtea.classpath.org/bugzilla
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x00005565ead9c800):  JavaThread "http-nio-8889-exec-9" daemon [_thread_in_native, id=109, stack(0x00007fe8b66e6000,0x00007fe8b67e6ad0)]

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x000000000000d1f6

(省略部分)

Stack: [0x00007fe8b66e6000,0x00007fe8b67e6ad0],  sp=0x00007fe8b67e1558,  free space=1005k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  0x000000000000d1f6

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.bytedeco.javacpp.avformat.avformat_open_input(Lorg/bytedeco/javacpp/avformat$AVFormatContext;Ljava/lang/String;Lorg/bytedeco/javacpp/avformat$AVInputFormat;Lorg/bytedeco/javacpp/avutil$AVDictionary;)I+0
j  org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe()V+624
j  org.bytedeco.javacv.FFmpegFrameGrabber.start()V+1
j  com.megvii.qingqiu.middle.platform.provider.util.VideoFrameUtil.fetchFrame(Ljava/io/File;Ljava/io/File;)V+26
j  com.megvii.qingqiu.middle.platform.provider.util.VideoFrameUtil.fetchFrame(Lorg/springframework/web/multipart/MultipartFile;)Ljava/io/File;+148
j  

(省略部分)

?現(xiàn)在將 ffmpeg 截取的方式改為 jcodecjcodec-javase 來處理。

  • 導入pom依賴:
  <dependency>
            <groupId>org.jcodec</groupId>
            <artifactId>jcodec</artifactId>
            <version>0.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.jcodec</groupId>
            <artifactId>jcodec-javase</artifactId>
            <version>0.2.5</version>
        </dependency>

        <!--<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>-->
  • ?工具類
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.jcodec.api.FrameGrab;
import org.jcodec.api.JCodecException;
import org.jcodec.common.model.Picture;
import org.jcodec.scale.AWTUtil;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * 視頻操作工具類
 */
@Slf4j
public class VideoUtils {

    /*** 圖片格式*/
    private static final String FILE_EXT = "jpg";

    /*** 幀數(shù)*/
    private static final int THUMB_FRAME = 5;

    /**
     * 獲取指定視頻的幀并保存為圖片至指定目錄
     *
     * @param videoFilePath 源視頻文件路徑
     * @param frameFilePath 截取幀的圖片存放路徑
     */
    public static void fetchFrame(String videoFilePath, String frameFilePath) throws Exception {
        File videoFile = new File(videoFilePath);
        File frameFile = new File(frameFilePath);
        getThumbnail(videoFile, frameFile);
    }

    /**
     * 獲取指定視頻的幀并保存為圖片至指定目錄
     *
     * @param videoFile  源視頻文件
     * @param targetFile 截取幀的圖片
     */
    public static void fetchFrame(MultipartFile videoFile, File targetFile) throws Exception {
        File file = new File(videoFile.getName());
        FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file);
        getThumbnail(file, targetFile);
    }

    /**
     * 獲取指定視頻的幀并保存為圖片至指定目錄
     *
     * @param videoFile 源視頻文件
     */
    public static File fetchFrame(MultipartFile videoFile) {
        String originalFilename = videoFile.getOriginalFilename();
        File file = new File(originalFilename);
        File targetFile = null;
        try {
            FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file);

            int i = originalFilename.lastIndexOf(".");
            String imageName;

            if (i > 0) {
                imageName = originalFilename.substring(0, i);
            } else {
                imageName = UUID.randomUUID().toString().replace("-", "");
            }
            imageName = imageName + ".jpg";
            targetFile = new File(imageName);
            getThumbnail(file, targetFile);
        } catch (Exception e) {
            log.error("獲取視頻指定幀異常:", e);
        } finally {
            if (file.exists()) {
                file.delete();
            }
        }
        log.debug("視頻文件 - 幀截取 - 處理結束");
        return targetFile;
    }

    /**
     * 獲取第一幀縮略圖
     *
     * @param videoFile  視頻路徑
     * @param targetFile 縮略圖目標路徑
     */
    public static void getThumbnail(File videoFile, File targetFile) {
        try {
            // 根據(jù)擴展名創(chuàng)建一個新文件路徑
            Picture picture = FrameGrab.getFrameFromFile(videoFile, THUMB_FRAME);
            BufferedImage bufferedImage = AWTUtil.toBufferedImage(picture);
            ImageIO.write(bufferedImage, FILE_EXT, targetFile);
        } catch (IOException | JCodecException e) {
            e.printStackTrace();
            log.error("獲取第一幀縮略圖異常:", e);
        }
    }

    public static void main(String[] args) {
        try {
            long startTime = System.currentTimeMillis();
            getThumbnail(new File("C:\\Users\\admin\\Desktop\\test.mp4"), new File("C:\\Users\\admin\\Desktop\\test.jpg"));
            System.out.println("截取圖片耗時:" + (System.currentTimeMillis() - startTime));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

二、使用第三方存儲自帶的方法實現(xiàn)(如阿里云OSS、華為云OBS)

如果我們的視頻是上傳并保存在第三方服務器上的,那么,我們可以使用阿里提供的視頻截幀方法,根據(jù)url直接截取視頻的指定幀。
具體方法就是在視頻的 url 后面,加上一些參數(shù),然后訪問這個新的url即可得到指定的截圖。
以下是以阿里云OSS為例:

要加入的參數(shù):
"?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto"

新的url:
"https://gnd.oss-cn-zhangjiakou.aliyuncs.com/vidio/test.map?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto" (直接訪問這個新的url即可得到截圖)

參數(shù)說明?

java獲取視頻的第一幀,java,音視頻,spring boot,阿里云

注意事項

  • 僅支持對視頻編碼格式為H264和H265的視頻文件進行視頻截幀。
  • OSS默認不保存視頻截幀的圖片,視頻截幀的圖片需手動下載并保存至本地。

親測了一下,主流的視頻格式,如:mp4、mov、avi等均可以采用這種方式進行截幀。

具體操作請參見阿里官方文檔:阿里云視頻截幀操作文檔

其它的第三方的云存儲跟阿里云的用法,大同小異,根據(jù)各自的說明文檔,進行開發(fā)就行。

如果這篇文章對您有所幫助,或者有所啟發(fā)的話,求一鍵三連:點贊、評論、收藏?關注,您的支持是我堅持寫作最大的動力。?文章來源地址http://www.zghlxwxcb.cn/news/detail-740746.html

到了這里,關于Java實現(xiàn)截取視頻第一幀的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 前端截取視頻第一幀作為封面

    概述 1.做項目的時候突然想截取視頻第一幀,作為視頻的封面,然后搜了很多博客都發(fā)現(xiàn)得到空白的圖片,最后得到了解決。 2.方法:通過創(chuàng)建canvas標簽,利用其drawImage() 方法在畫布上繪制該視頻,然后運用toDataURL方法轉換canvas上的圖片為base64格式,并將base64格式的圖片作為

    2023年04月23日
    瀏覽(25)
  • 純前端播放文件流視頻并預覽并截取視頻第一幀

    1、把文件流轉為本地可以播放地址 調用 getFileURL 并傳入文件流會返回一個地址,將地址賦值給 video 的 src 即可播放視頻,無需上傳至服務器。 2、截取視頻第一幀 調用 getVideoBase64 并將第一步得到的url轉給 getVideoBase64 即可得到視頻第一幀圖片, getVideoBase64 返回的片為 base64

    2023年04月09日
    瀏覽(21)
  • video截取視頻第一幀作為播放前默認圖片

    重要!不設置會導致第一幀圖片不顯示 實現(xiàn)js 附上全部代碼

    2024年02月12日
    瀏覽(23)
  • js(ts)截取視頻第一幀作為封面圖

    直接上代碼: 這里有三個地方需要注意: 1. 需要加上 preload 屬性 這是防止截圖結果為黑屏的關鍵一步 2. canvas寬高的設置 網(wǎng)絡上其它文章的代碼都直接讀取 video.width 和 video.height ,會導致如果是豎視頻截取出來的封面圖在橫顯示時會變形 3. 判斷圖片有效性 有時候截取到的圖

    2024年02月10日
    瀏覽(22)
  • uni-app App和H5平臺上傳視頻截取視頻第一幀生成圖片

    uni-app App和H5平臺上傳視頻截取視頻第一幀生成圖片

    提示:因為uni-app中renderjs僅支持App和H5平臺,所以該方案僅支持當前這兩個平臺。 this.request為本人封裝的接口請求方法,可以替換成個人的接口請求方法,如有需要可在下方留言 因為uni-app App端沒有dom概念,不支持dom操作,并且uni-app的canvas不支持繪制video。renderjs完美解決了

    2023年04月09日
    瀏覽(30)
  • get兩個js小技能——JS截取視頻第一幀&圖片轉Base64

    get兩個js小技能——JS截取視頻第一幀&圖片轉Base64

    由于開發(fā)之前做的VisualDrag拖拽模板優(yōu)化的時候,拖拽進去的圖片、視頻文件等需要進行截圖作為封面,目前采用的截圖方法是htme2canvas,使用canvas進行的截圖操作,所以就會遇到這樣的問題,視頻和圖片圖床簡單的使用標簽加入canvas畫布里面無法正確的截圖成功。最后采取的

    2024年02月12日
    瀏覽(20)
  • JS 截取視頻某一幀圖片 實現(xiàn)視頻截圖

    JS 截取視頻某一幀圖片 實現(xiàn)視頻截圖

    第一步:創(chuàng)建video用于存放需要截取的視頻文件 第二步:創(chuàng)建canvas畫布,用于繪制截取到的圖片 1,定義創(chuàng)建一個 canvas 標簽; 2,指定 canvas 標簽的寬高; 3, 調用canvas元素中的 getContext() 方法(返回一個用于在畫布上繪圖的環(huán)境)。 要注意的是 drawImage() 的第一個參數(shù)不再是player而

    2024年02月12日
    瀏覽(17)
  • JavaScrip獲取視頻第一幀作為封面圖

    在JavaScript中,你可以使用HTML5的video元素來加載視頻,然后使用Canvas來捕獲視頻的第一幀作為封面圖。以下是一個簡單的例子: 請注意,這個例子中使用了loadeddata事件,該事件在視頻的第一幀加載完成后觸發(fā)。這里創(chuàng)建了一個Canvas元素,通過drawImage方法將視頻的第一幀繪制在

    2024年01月16日
    瀏覽(16)
  • JS 怎么獲取視頻第一幀作為封面圖?

    要獲取視頻的第一幀作為封面圖,你可以使用HTML5的 video 元素和 JavaScript 來實現(xiàn)。下面是一個簡單的步驟: 在HTML中,創(chuàng)建一個 video 元素,并設置視頻的路徑或URL: 在JavaScript中,獲取 video 元素的引用,并監(jiān)聽它的 loadedmetadata 事件(視頻元數(shù)據(jù)加載完成時觸發(fā)): 繼續(xù)在JavaS

    2024年04月10日
    瀏覽(22)
  • Java使用LocalDate獲取某個月的第一天和最后一天日期

    以一個月為周期進行查詢時,如果用戶沒有選擇查詢的月份,我們想要默認查詢當月或上個月的數(shù)據(jù),這時,如何獲取到一個月的第一天和最后一天日期呢? 以下介紹兩種方式采用LocalDate格式日期的實現(xiàn),以及采用LocalDateTime格式日期的實現(xiàn)。直接上代碼! 輸出結果為:

    2023年04月20日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包