JAVA代碼調(diào)用ffmpeg程序進(jìn)行視頻轉(zhuǎn)碼和推流方式
一、前言
FFmpeg是一款多媒體視頻處理工具,有非常強(qiáng)大的功能包括:視頻采集、視頻推流、視頻格式轉(zhuǎn)換、視頻抓圖、給視頻加水印等功能。
FFmpeg本身是一個(gè)命令行程序,需要通過執(zhí)行 ffmpeg命令來實(shí)現(xiàn)功能,如下:
ffmpeg -i 123.mp4 -c:a copy -c:v libx264 -f flv rtmp://127.0.0.1:1935/live/test ffmpeg -i 123.mp4 -c copy -f hls -hls_list_size 5 -hls_flags 50 -hls_time 10 D:\hls\test.m3u8
在實(shí)際開發(fā)工作中,會需要通過JAVA代碼去調(diào)用ffmpeg程序去完成功能,而不是手動去執(zhí)行ffmpeg命令。本篇文章將介紹如何通過JAVA代碼去調(diào)用執(zhí)行ffmpeg程序。
二、JAVA代碼調(diào)用ffmpeg
本篇文章將介紹兩種方式實(shí)現(xiàn) JAVA代碼去調(diào)用ffmpeg程序。
方式一:采用第三方封裝調(diào)用ffmpeg接口的jar包實(shí)現(xiàn)
1. 在Maven項(xiàng)目pom.xml文件中引入jar包依賴
<dependency> <groupId>net.bramp.ffmpeg</groupId> <artifactId>ffmpeg</artifactId> <version>0.6.2</version> </dependency>
2. 編寫java代碼
//創(chuàng)建FFmpeg對象 FFmpeg ffmpeg = new FFmpeg("D:\\ffmpeg\\bin\\ffmpeg.exe"); //參數(shù)是:ffmpeg命令工具的安裝路徑 //創(chuàng)建FFmpegBuilder對象,設(shè)置推流/轉(zhuǎn)碼參數(shù) FFmpegBuilder builder = new FFmpegBuilder() .setInput("D:\\111.mp4") //輸入視頻源地址 .overrideOutputFiles(true) //設(shè)置是否覆蓋已存在的輸出文件 .addOutput("D:\\hls\\test.m3u8") //輸出流地址 .setFormat("hls") //輸出流格式 -f hls .setAudioCodec("copy") //設(shè)置音頻轉(zhuǎn)碼 copy表示不轉(zhuǎn)碼 .setVideoCodec("libx264") //設(shè)置視頻轉(zhuǎn)碼 copy表示不轉(zhuǎn)碼 .setVideoQuality(1) //設(shè)置視頻質(zhì)量,一般為1到5(1代表質(zhì)量最高) .setVideoFrameRate(25) //設(shè)置視頻幀率 .addExtraArgs("-t", "30") //設(shè)置推流持續(xù)時(shí)間 .addExtraArgs("-hls_list_size", "5") //設(shè)置輸出文件個(gè)數(shù)(hls輸出流特有的參數(shù)) .addExtraArgs("-hls_flags", "50") //設(shè)置輸出文件替換(hls輸出流特有的參數(shù)) .addExtraArgs("-hls_time", "6") //設(shè)置輸出文件每個(gè)時(shí)長多少秒(hls輸出流特有的參數(shù)) .done(); //最后調(diào)用done()完成參數(shù)配置 //創(chuàng)建FFmpegExecutor對象,用于執(zhí)行ffpmeg轉(zhuǎn)流任務(wù) FFmpegExecutor executor=new FFmpegExecutor(ffmpeg); //執(zhí)行ffpmeg轉(zhuǎn)流任務(wù),并添加了監(jiān)聽器ProgressListener,可以監(jiān)聽ffpmeg運(yùn)行狀態(tài)情況 executor.createJob(builder, new ProgressListener() { @Override public void progress(Progress progress) { System.out.println("-----------"); System.out.println(progress); } }).run();
3. 第三方j(luò)ar包實(shí)現(xiàn)優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):封裝好了ffmpeg調(diào)用功能,代碼實(shí)現(xiàn)簡單易用
- 缺點(diǎn):沒有提供停止ffmpeg程序的方法,無法實(shí)現(xiàn)手動終止任務(wù)。就算手動殺死JAVA程序也無法終止ffmpeg程序的執(zhí)行,只有等ffmpeg轉(zhuǎn)流任務(wù)完成了程序自行停止。
方式二:采用ProcessBuilder類創(chuàng)建進(jìn)程的方式調(diào)用ffmpeg實(shí)現(xiàn)
ProcessBuilder 類是JDK中java.lang包下提供的用于創(chuàng)建操作系統(tǒng)進(jìn)程的類, 可以通過JDK API 文檔查看其用法。
1. 編寫java代碼
//創(chuàng)建一個(gè)命令List集合,用于存放ffmpeg執(zhí)行的命令參數(shù) List<String> command = new ArrayList<>(); command.add("D:\\ffmpeg\\bin\\ffmpeg.exe"); command.add("-i"); command.add("D:\\123.mp4"); //輸入視頻源或者流地址 command.add("-c"); command.add("copy"); command.add("-f"); command.add("hls"); command.add("-hls_time"); command.add("10"); command.add("-hls_list_size"); command.add("5"); command.add("-hls_flags"); command.add("50"); command.add("D:\\hls\\test.m3u8"); //輸出流地址 //創(chuàng)建ProcessBuilder對象,傳入集合 ProcessBuilder builder = new ProcessBuilder(command); //start()方法創(chuàng)建一個(gè)系統(tǒng)進(jìn)程,執(zhí)行ffmpeg命令工具 Process process = builder.start(); //注意:使用ProcessBuilder執(zhí)行任務(wù),必須要手動接收正常輸出信息和錯(cuò)誤輸出信息,不然ProcessBuilder任務(wù)會阻塞卡住 //多線程讀取正常輸出信息 process.getInputStream() new Thread(() -> { try { InputStream is = process.getInputStream(); //將正常輸出信息寫入到normal.txt文件中 RandomAccessFile raf = new RandomAccessFile("D:\\normal.txt", "rw"); byte[] data = new byte[128]; int len = -1; while((len = is.read(data)) != -1) { raf.write(data, 0, len); } raf.close(); } catch (IOException e) { e.printStackTrace(); } }, "Thread-Normal").start(); //多線程讀取錯(cuò)誤輸出信息 process.getErrorStream() new Thread(() -> { try { InputStream is = process.getErrorStream(); //將錯(cuò)誤輸出信息寫入到error.txt文件中 RandomAccessFile raf = new RandomAccessFile("D:\\error.txt", "rw"); byte[] data = new byte[128]; int len = -1; while((len = is.read(data)) != -1) { raf.write(data, 0, len); } raf.close(); } catch (IOException e) { e.printStackTrace(); } }, "Thread-Error").start(); //destroy()方法可以停止進(jìn)程,從而終止ffmpeg程序 //process.destroy();
2. ProcessBuilder實(shí)現(xiàn)優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):可以手動調(diào)用destory()方法隨時(shí)停止ffmpeg程序的執(zhí)行
- 缺點(diǎn):需要手動寫代碼去主動接收任務(wù)進(jìn)程產(chǎn)生的正常輸出信息和錯(cuò)誤信息,不然進(jìn)程會被卡住。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpingMvc復(fù)雜參數(shù)傳收總結(jié)
這篇文章主要為大家介紹了SpingMvc復(fù)雜參數(shù)傳收總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08SpringBoot中將@Bean方法解析為BeanDefinition詳解
這篇文章主要介紹了SpringBoot中將@Bean方法解析為BeanDefinition詳解,得到的BeanDefinition是ConfigurationClassBeanDefinition類型,會為BeanDefinition設(shè)置factoryMethodName,這意味著當(dāng)實(shí)例化這個(gè)bean的時(shí)候?qū)⒉捎霉S方法,需要的朋友可以參考下2023-12-12Java基于JavaMail實(shí)現(xiàn)向QQ郵箱發(fā)送郵件
這篇文章主要為大家詳細(xì)介紹了Java基于JavaMail實(shí)現(xiàn)向QQ郵箱發(fā)送郵件的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01SpringBoot集成Tess4J實(shí)現(xiàn)OCR的示例代碼
Tess4J是一個(gè)基于Tesseract OCR引擎的Java接口,可以用來識別圖像中的文本,說白了,就是封裝了它的API,讓Java可以直接調(diào)用,本文給大家介紹了SpringBoot集成Tess4J實(shí)現(xiàn)OCR的示例,需要的朋友可以參考下2024-12-12ThreadLocal導(dǎo)致JVM內(nèi)存泄漏原因探究
ThreadLocal是JDK提供的線程本地變量機(jī)制,但若使用不當(dāng)可能導(dǎo)致內(nèi)存泄漏。正確的使用方式是在使用完后及時(shí)remove,或者使用弱引用等手段避免強(qiáng)引用導(dǎo)致的內(nèi)存泄漏。在多線程編程中,合理使用ThreadLocal可以提高并發(fā)性能,但也需要注意其潛在的內(nèi)存泄漏問題2023-04-04