如何在Java JVM中处理图像和视频
在Java JVM中處理圖像(更不用說視頻)一直是一項艱巨的任務。 自JDK7以來, ImageIO類已經走了很長一段路,再加上常見的SDK錯誤,并不總是能給您您所期望的(圖像質量差,不總是支持所有類型的JPEG標準,…)。 在這行的最后,最好使用專門為圖像處理編寫的開源庫,例如ImageMagick和GraphicsMagick。 這些庫也是我們在ImageServer跨模塊中使用的庫,用于為圖像,PDF等生成縮略圖和變體。
最近,我們參與了一個項目,在該項目中,我們不得不顯示和播放客戶上傳的音頻/視頻文件。 該頁面還顯示了媒體資產中的一些元數據,文件在上傳后將被拒絕(例如,如果比特率或其他元數據不足)。 簡而言之,我們必須解析各種音頻和視頻資產的元數據,然后將此媒體文件呈現給客戶。 我們這里不是在談論Netflix流媒體平臺,而是一些基本的音頻/視頻流媒體。
我們尋找的庫可以解析視頻文件(在本例中,我們正在談論MXF文件)以提取元數據。 有類似Netflix Photon( https://github.com/Netflix/photon/releases )和https://github.com/jforaci/mxf-reader的庫 。 但是,您真的要在JVM中解析和讀取文件嗎? 簡短的答案是“不”,您不希望所有這些東西都進入Java內存。
那有什么選擇呢?
元數據解析
為此,我們研究了ffmpeg和MediaInfo。
如果您曾經將自己的(S)VCD,DVD磁盤轉換為MKV(Matroska容器)或AVI,MPEG格式,那么您肯定會注意到ffmpeg是用于轉換/解析媒體文件的事實上的工具。
MediaInfo是客戶建議的工具,可從媒體文件提供結構化的元數據探測。
我們編寫的解析器支持ffmpeg和Mediainfo的靈活性,并將這些工具中的JSON映射到相同的數據結構。 兩者給出相似的輸出
ffmpeg探針
$ ffprobe -show_format -show_streams audiocheck.net_polarity_guitarOK.wav -print_format json -loglevel 0 {"streams": [{"index": 0,"codec_name": "pcm_s16le","codec_long_name": "PCM signed 16-bit little-endian","codec_type": "audio","codec_time_base": "1/44100","codec_tag_string": "[1][0][0][0]","codec_tag": "0x0001","sample_fmt": "s16","sample_rate": "44100","channels": 2,"bits_per_sample": 16,"r_frame_rate": "0/0","avg_frame_rate": "0/0","time_base": "1/44100","duration_ts": 224041,"duration": "5.080295","bit_rate": "1411200","disposition": {"default": 0,"dub": 0,"original": 0,"comment": 0,"lyrics": 0,"karaoke": 0,"forced": 0,"hearing_impaired": 0,"visual_impaired": 0,"clean_effects": 0,"attached_pic": 0,"timed_thumbnails": 0}}],"format": {"filename": "audiocheck.net_polarity_guitarOK.wav","nb_streams": 1,"nb_programs": 0,"format_name": "wav","format_long_name": "WAV / WAVE (Waveform Audio)","duration": "5.080295","size": "896208","bit_rate": "1411269","probe_score": 99} } $ mediainfo --output=JSON audiocheck.net_polarity_guitarOK.wav { "media": { "@ref": "audiocheck.net_polarity_guitarOK.wav", "track": [ { "@type": "General", "AudioCount": "1", "FileExtension": "wav", "Format": "Wave", "FileSize": "896208", "Duration": "5.080", "OverallBitRate_Mode": "CBR", "OverallBitRate": "1411351", "StreamSize": "44", "File_Modified_Date": "UTC 2020-03-03 12:02:30", "File_Modified_Date_Local": "2020-03-03 13:02:30" }, { "@type": "Audio", "Format": "PCM", "Format_Settings_Endianness": "Little", "Format_Settings_Sign": "Signed", "CodecID": "1", "Duration": "5.080", "BitRate_Mode": "CBR", "BitRate": "1411200", "Channels": "2", "SamplingRate": "44100", "SamplingCount": "224028", "BitDepth": "16", "StreamSize": "896164", "StreamSize_Proportion": "0.99995" } ] } }請注意,如果您使用的是Debian常規安裝,則需要從https://mediaarea.net/zh-CN/MediaInfo/Download/Debian安裝.deb軟件包–否則,您將被(非常)舊版本所困擾,該版本具有沒有JSON輸出。
將這些輸出包裝到一個通用的數據結構中足以完成我們的元數據處理檢查并存儲一些元數據以用于顯示(例如,媒體文件的持續時間和格式)。
縮圖產生
對于縮略圖的生成,有兩個要求。 音頻文件必須生成波形。 視頻文件必須為該視頻生成良好的縮略圖。
根據上面的元數據,您可以快速區分上傳的媒體文件是音頻文件還是視頻文件(視頻文件具有視頻流/軌道)。
兩者都遵循另一條縮略圖生成軌道。
音頻縮略圖生成和音頻播放
要在概覽頁面上顯示波形,我們只需使用ffmpeg使用以下命令生成波形
$ ffmpeg -y -i inputfile -filter_complex "showwavespic=colors=#007bff:split_channels=1" -frames:v 1 -c:v png -loglevel -8這將生成PNG格式的波形,并拆分波形中的不同音頻通道。 生成此圖像后,我們將其上傳到我們的Across ImageServer。
在音頻資產的詳細信息頁面上,我們使用WaveSurfer( https://wavesurfer-js.org/ )播放音頻文件并渲染音頻通道-那里沒什么特別的。
視頻縮略圖生成和視頻播放
要在概述頁面上顯示縮略圖,我們可以使用ffmpeg縮略圖過濾器
$ ffmpeg -i inputFile -vf "thumbnail" -frames:v 1該過濾器非常適合于對優質縮略圖進行評價。 您可以做更多更有趣的事情,例如
$ ffmpeg -ss 3 -i inputFile -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.png這將生成5個縮略圖幀,從一開始就跳過3秒鐘(可能是字幕),并抓取“場景變化”大于50%的幀。 為此,在https://superuser.com/questions/538112/含義ful-thumbnails- for-a-video-using- ffmpeg進行了很好的討論。
最終,客戶認為最后一個第二幀將是最適合他們的目的的,因為該幀通常包含商業視頻的閉包。
由于視頻為25fps,我們最終得到的命令如下(其中89是幀總數– 26 )。 是的,26…因為ffmpeg對幀進行從零開始的計數。
$ ffmpeg -i inputFile -vf "select=gte(n\,89)" -frames:v 1然后將生成的縮略圖上傳到ImageServer中,僅此而已。 現在...播放視頻文件...
嗯,網絡上的視頻播放器不支持MXF文件,最好的選擇是將該視頻容器格式轉碼為MP4(這是當今最兼容的跨瀏覽器格式)。
幸運的是,ffmpeg可以解救,盡管要找到合適的命令來生成可在大多數瀏覽器中播放的MP4的命令可能具有挑戰性。
$ ffmpeg -y -i inputFile -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -level 3 transcodedFile此命令生成具有基線配置文件和YUV420P顏色編碼方案的MP4文件。 此基準配置文件和配色方案可確保在Safari(適用于Mac)上正確顯示。
使用Across FileRepositoryModule將轉碼后的文件存儲在后備存儲(在這種情況下為Azure BLOB存儲,但它也支持AWS S3或本地存儲)。
現在...真正播放視頻文件...
我們需要網絡上的視頻播放器來實現這一目標。 最常見的庫是videojs( https://videojs.com/ ),該庫易于設置且可自定義,足以滿足我們的目的。
僅向<video>標簽提供正確的url即可在Firefox和Chrome中立即產生結果,但是Safari頑固地播放該文件。
Safari嘗試通過將范圍標頭添加到HTTP請求中,從而與其他蘋果產品一樣變得與眾不同。 這是為了避免一次通過網絡發送視頻文件中的所有字節。
取而代之的是HTTP Range標頭指定需要獲取的字節范圍。
使用Spring Boot中的ResourceRegion構造可以輕松完成此操作,以下博客對此有所幫助: https : //melgenek.github.io/spring-video-service
最后,安裝程序能夠:
- 從任何媒體文件中提取元數據
- 生成媒體文件的縮略圖(音頻波形和視頻縮略圖)
- 通過Wavesurfer播放音頻文件
- 通過VideoJS播放視頻文件
翻譯自: https://www.javacodegeeks.com/2020/04/how-to-process-images-and-videos-within-java-jvm.html
總結
以上是生活随笔為你收集整理的如何在Java JVM中处理图像和视频的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无名ddos下载(无名ddos群集)
- 下一篇: 苹果13震动快捷键(苹果13震动怎么调出