Java基于FFmpeg實(shí)現(xiàn)Mp4視頻轉(zhuǎn)GIF
背景
在一些業(yè)務(wù)場(chǎng)景中,會(huì)有如下的一些要求:比如有用戶需要將Mp4視頻轉(zhuǎn)為Gif動(dòng)圖。當(dāng)然有一些小伙伴說可以使用系統(tǒng)截圖,然后使用之前提到過的技術(shù):GIF圖像動(dòng)態(tài)生成-JAVA后臺(tái)生成。需要處理的素材比較少,就一兩個(gè)視頻,確實(shí)可以通過這種方式來處理。試想一下,如果需要處理上百個(gè),做處理的小伙伴是不是就抓狂了,這完全是實(shí)打?qū)嵉墓ぷ髁俊D怯袥]有直接從Mp4轉(zhuǎn)成gif動(dòng)態(tài)圖的技術(shù)呢?運(yùn)營的小伙伴就能按時(shí)下班了。
經(jīng)過一番查詢,找到一些思路,Mp4視頻的組成也是一幀一幀的圖像組成的。如果有什么技術(shù)可以去動(dòng)態(tài)獲取這些數(shù)據(jù),通過動(dòng)態(tài)截取每一幀,最后再合成圖片。不久解決了嗎?FFmpeg變進(jìn)入技術(shù)選型的視野。本文主要講解如何在Java中,使用FFmpeg進(jìn)行視頻的幀讀取,并最終合并成Gif動(dòng)態(tài)圖。
一、FFmpeg是什么
1、簡介
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。FFmpeg在Linux平臺(tái)下開發(fā),但它同樣也可以在其它操作系統(tǒng)環(huán)境中編譯運(yùn)行,包括Windows、Max Os等。這個(gè)項(xiàng)目最早由Fabrice Bellard發(fā)起,2004年至2015年間由Michael Niedermayer主要負(fù)責(zé)維護(hù)。許多FFmpeg的開發(fā)人員都來自項(xiàng)目MPlayer,而且當(dāng)前FFmpeg也是放在MPlayer項(xiàng)目組的服務(wù)器上。
2、FFmpeg功能列表
FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序。它包括了領(lǐng)先的音/視頻編碼庫libavcodec等。
- libavformat:用于各種音視頻封裝格式的生成和解析,包括獲取解碼所需信息以生成解碼上下文結(jié)構(gòu)和讀取音視頻幀等功能;
- libavcodec:用于各種類型聲音/圖像編解碼;
- libavutil:包含一些公共的工具函數(shù);
- libswscale:用于視頻場(chǎng)景比例縮放、色彩映射轉(zhuǎn)換;
- libpostproc:用于后期效果處理;
- ffmpeg:該項(xiàng)目提供的一個(gè)工具,可用于格式轉(zhuǎn)換、解碼;
- ffsever:一個(gè) HTTP 多媒體即時(shí)廣播串流服務(wù)器;
- ffplay:是一個(gè)簡單的播放器,使用ffmpeg 庫解析和解碼,通過SDL顯示;
二、Java集成JavaCV調(diào)用FFmpeg
1、JavaCv引入
JavaCv是基于openCv的一個(gè)非常強(qiáng)大的庫,關(guān)于javaCv以后計(jì)劃做幾次講解,這里不深入,有興趣的小伙伴可以先行學(xué)習(xí)。在工程中新建一個(gè)Maven工程,在Pom.xml中引入支持,需要注意的是,這里為了演示簡單,引入了完整的JavaCv的包,在實(shí)際項(xiàng)目中不需要如此,按需引入即可。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yelang</groupId> <artifactId>mp42gif</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.2</version> </dependency> <!-- https://mvnrepository.com/artifact/com.madgag/animated-gif-lib --> <dependency> <groupId>com.madgag</groupId> <artifactId>animated-gif-lib</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- lombok 代碼自動(dòng)生成組件 add by wuzuhu on 2022-11-01 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> </dependencies> </project>
2、視頻轉(zhuǎn)換讀取
public static void main(String[] args) { // 將指定目錄的 MP4 文件生成同名的 gif 文件 File videoDir = new File("E:/testv"); for (File file : videoDir.listFiles()) { String videoPath = file.getPath(); if (videoPath.endsWith(".mp4")) { String gifPath = videoPath.substring(0, videoPath.lastIndexOf(".")) + ".gif"; try { video2Gif(videoPath, gifPath); System.out.println("轉(zhuǎn)換完成"); } catch (Exception e) { System.out.println("文件 [" + videoPath + "] 處理異常!"); e.printStackTrace(); } } } }
上面定義了一個(gè)main函數(shù)調(diào)用,只是一個(gè)簡單的示例,實(shí)際項(xiàng)目需要自己擴(kuò)展。核心的視頻轉(zhuǎn)換函數(shù)如下:
private static void video2Gif(String videoPath, String gifPath) throws Exception { try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoPath); FileOutputStream targetFile = new FileOutputStream(gifPath)) { grabber.start(); int frames = grabber.getLengthInFrames(); System.out.println(frames); AnimatedGifEncoder encoder = new AnimatedGifEncoder(); encoder.setFrameRate(frames); encoder.start(targetFile); Java2DFrameConverter converter = new Java2DFrameConverter(); for (int i = 0; i < frames; i += 8) {// 8幀合成1幀?(反正越大動(dòng)圖越小、越快) encoder.setDelay((int) grabber.getDelayedTime()); encoder.addFrame(converter.convert(grabber.grabImage())); grabber.setFrameNumber(i); } encoder.finish(); } }
通過FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoPath);獲取視頻信息,同時(shí)調(diào)用grabber.start();進(jìn)行視頻讀?。ㄟ@一步必須要設(shè)置,否則會(huì)影響后面的結(jié)果)。通過int frames = grabber.getLengthInFrames();獲取Mp4視頻的幀數(shù),再循環(huán)幀,即可。上述的代碼中不是讀取每一幀,這樣生成的結(jié)果會(huì)非常大,建議不要全部讀取。
for (int i = 0; i < frames; i += 8) {// 8幀合成1幀) encoder.setDelay((int) grabber.getDelayedTime()); encoder.addFrame(converter.convert(grabber.grabImage())); grabber.setFrameNumber(i); }
3、運(yùn)行結(jié)果
使用一段視頻來測(cè)試相應(yīng)的功能能否正常生效,在E盤新建一個(gè)mp4視頻文件。
使用上述視頻來驗(yàn)證代碼是否正確運(yùn)行,通過Debug來觀察程序的運(yùn)行。
最后在測(cè)試的目錄中,發(fā)現(xiàn)已經(jīng)成功生成對(duì)應(yīng)的gif圖片,拖到瀏覽器中可以正常展示。
三、總結(jié)
本文主要簡單介紹了在Java中如何基于FFmpeg進(jìn)行Mp4視頻到Gif動(dòng)圖的轉(zhuǎn)換。首先簡單講解FFmpeg的定義,常用的方法,然后重點(diǎn)介紹JavaCv中FFmpeg具體使用,如果在工作中有這種需要,不妨采用這種方式。
以上就是Java基于FFmpeg實(shí)現(xiàn)Mp4視頻轉(zhuǎn)GIF的詳細(xì)內(nèi)容,更多關(guān)于Java FFmpeg Mp4轉(zhuǎn)GIF的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Javacv使用ffmpeg實(shí)現(xiàn)音視頻同步播放
- Java利用ffmpeg實(shí)現(xiàn)視頻MP4轉(zhuǎn)m3u8
- java使用ffmpeg實(shí)現(xiàn)上傳視頻的轉(zhuǎn)碼提取視頻的截圖等功能(代碼操作)
- Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼
- java調(diào)用ffmpeg實(shí)現(xiàn)轉(zhuǎn)換視頻
- Java+Windows+ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換功能
- 詳解java調(diào)用ffmpeg轉(zhuǎn)換視頻格式為flv
- java調(diào)用ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換的方法
- Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)
相關(guān)文章
Mybatis動(dòng)態(tài)SQL之IF語句詳解
這篇文章主要給大家介紹了關(guān)于Mybatis動(dòng)態(tài)SQL之IF語句的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Java函數(shù)式編程(三):列表的轉(zhuǎn)化
這篇文章主要介紹了Java函數(shù)式編程(二):列表的轉(zhuǎn)化,lambda表達(dá)式不僅能幫助我們遍歷集合,并且可以進(jìn)行集合的轉(zhuǎn)化,需要的朋友可以參考下2014-09-09Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)
這篇文章主要介紹了Spring中BeanFactory和ApplicationContext的作用和區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Java實(shí)現(xiàn)經(jīng)典大富翁游戲的示例詳解
大富翁,又名地產(chǎn)大亨。是一種多人策略圖版游戲。參與者分得游戲金錢,憑運(yùn)氣(擲骰子)及交易策略,買地、建樓以賺取租金。本文將通過Java實(shí)現(xiàn)這一經(jīng)典游戲,感興趣的可以跟隨小編一起學(xué)習(xí)一下2022-02-02SpringBoot?調(diào)用外部接口的三種實(shí)現(xiàn)方法
Spring Boot調(diào)用外部接口的方式有多種,常見的有以下三種方式:RestTemplate、Feign 和 WebClient,本文就詳細(xì)介紹一下,感興趣的可以了解一下2023-08-08Java使用poi做加自定義注解實(shí)現(xiàn)對(duì)象與Excel相互轉(zhuǎn)換
這篇文章主要介紹了Java使用poi做加自定義注解實(shí)現(xiàn)對(duì)象與Excel相互轉(zhuǎn)換,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05詳解Spring Boot 項(xiàng)目部署到heroku爬坑
這篇文章主要介紹了詳解Spring Boot 項(xiàng)目部署到heroku爬坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08java配置dbcp連接池(數(shù)據(jù)庫連接池)示例分享
java配置dbcp連接池示例分享,大家參考使用吧2013-12-12JAVA裝飾者模式(從現(xiàn)實(shí)生活角度理解代碼原理)
裝飾者模式可以動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來說,Decorator模式相比生成子類更為靈活。這篇文章主要介紹了JAVA裝飾者模式的相關(guān)資料,需要的朋友可以參考下2016-12-12