JAVA經過URL連接獲取視頻文件信息(無需下載文件)

最近項目碰到一個大坑:APP上須要在獲取視頻列表時就獲取視頻的時長,但早期上傳的時候數據庫都沒有保存這個數據,因此前段時間添加一個時長字段,在上傳時手動輸入視頻時長,可是以前庫中有上萬條數據沒這個信息,若是這樣一條一條手動輸入,人都得瘋掉。因此誰也不提無論這破事,在這以前的視頻時長信息就讓它空在那。最近領導讓我作個按類目分類統計視頻時長信息,和領導反映了這個問題,最終解決方案就把沒有的作0處理。在完成了這個功能後,我就在想能用什麼方式把以前的視頻時長所有給更新上去。手動輸入這個確定時不行的,必須得java後臺來獲取錄入。但上網搜索了無數的帖子,最終經過java實現的只有一種方法能用,那就是先要下載到本地,而後再一個一個的遍歷查詢。看着服務器上的上萬個視頻,想一想這方法就讓人頭皮發麻。java

  雖然沒找到可行方法,但基本上都是用jave獲取視頻信息的。因而就去查看jave的官方API,瞭解到是經過FFmpeg處理多媒體文件,接着又查看FFmpeg的API,發現ffmpeg在命令行中使用時能夠經過url獲取視頻。但使用jave工具包時獲取MultimediaInfo就必須得傳入File,但是又不能經過url建立File。因而就就反編譯jave的jar從源碼上動手。git

複製代碼

// 源碼
public MultimediaInfo getInfo(File source)
        throws InputFormatException, EncoderException
    {
        FFMPEGExecutor ffmpeg;
        ffmpeg = locator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(source.getAbsolutePath());
        try
        {
            ffmpeg.execute();
        }
        catch(IOException e)
        {
            throw new EncoderException(e);
        }
        MultimediaInfo multimediainfo;
        RBufferedReader reader = null;
        reader = new RBufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
        multimediainfo = parseMultimediaInfo(source, reader);
        ffmpeg.destroy();
        return multimediainfo;
        Exception exception;
        exception;
        ffmpeg.destroy();
        throw exception;
    }

複製代碼

ffmpeg傳入參數時使用的是數據庫

source.getAbsolutePath()獲取文件的絕對路徑,因此經過url建立File在這是獲取的就是 項目路徑+url了。

而後就把傳入path修改爲了url,可是運行仍是出現 InputFormatException異常。好吧,那就繼續找問題吧服務器

而後debug發現雖然修改了path,可是這路徑細看仍是不對多線程

http://v1.v.123.com\11\919\2019\zb\0181.mp4
正確的url應該是這樣的:http://v1.v.123.com/11/919/2019/zb/0181.mp4

 接着更正問題。ide

if(path.indexOf("http") != -1) {
            path = source.getPath();
            path = path.split(":")[0] + "://" + path.split(":")[1].substring(1);
            path = path.replace("\\", "/");
        }

 

此次終於沒問題了,能夠正常使用了。而後還有下面這個方法的調用,源碼中有個獲取異常信息的也得修改path值工具

multimediainfo = parseMultimediaInfo(source, reader);

 這個也和只需重複上面的操做就OK了。這樣就徹底搞定了。性能

複製代碼

import lx.jave.AudioAttributes;
import lx.jave.AudioInfo;
import lx.jave.Encoder;
import lx.jave.EncoderException;
import lx.jave.EncodingAttributes;
import lx.jave.InputFormatException;
import lx.jave.MultimediaInfo;
import lx.jave.VideoInfo;
import lx.jave.VideoSize;

/**
 * jave多媒體工具類(需導出jave  jar包) 
 * @author longxiong
 *
 */
public class JaveToolsTest {

    public static void main(String[] args) throws InputFormatException, EncoderException, Exception {

        /**
         * 獲取本地多媒體文件信息
         */
        // 編碼器
        Encoder encoder = new Encoder();
        File file = new File("http://*****018.mp4");
        // 多媒體信息
        MultimediaInfo info = encoder.getInfo(file);
        // 時長信息
        long duration = info.getDuration();
        System.out.println("視頻時長爲:" + duration / 1000 + "秒");
        // 音頻信息
        AudioInfo audio = info.getAudio();
        int bitRate = audio.getBitRate();  // 比特率
        int channels = audio.getChannels();  // 聲道
        String decoder = audio.getDecoder();  // 解碼器
        int sRate = audio.getSamplingRate();  // 採樣率
        System.out.println("解碼器:" + decoder + ",聲道:" + channels + ",比特率:" + bitRate + ",採樣率:" + sRate);
        // 視頻信息
        VideoInfo video = info.getVideo();
        int bitRate2 = video.getBitRate();
        Float fRate = video.getFrameRate();  // 幀率
        VideoSize videoSize = video.getSize();
        int height = videoSize.getHeight();  // 視頻高度
        int width = videoSize.getWidth();  // 視頻寬度
        System.out.println("視頻幀率:" + fRate + ",比特率:" + bitRate2 + ",視頻高度:" + height + ",視頻寬度:" + width);
        }
}

複製代碼

 

 

雖然是比較簡單的修改,仍是附上修改後的jar包吧。測試

連接:https://pan.baidu.com/s/1gqsfl_2Tq2swbMY-mQUQeg 
提取碼:zpdh編碼

https://gitee.com/20eit/eit/blob/master/jave-lx-1.0.5.jar

附帶測試一下讀取性能:

單線程讀取20個視頻:

多線程(開啓了10個線程)讀取20個視頻:

從數據上看採用多線程性能仍是能夠的。差很少一秒鐘就能讀取一個了。不過幾千上萬的數據就不知道會不會崩了。下次有空在測試一下。

相關文章
相關標籤/搜索