java 通過ffmpeg 訪問網路圖片
阿新 • • 發佈:2021-08-17
參考:https://www.cnblogs.com/chenbinaiqiuyu/p/12736814.html
你可能用到的原因!!!
1 我使用儲存oss,儲存圖片/視訊。
而oss沒有提供圖片/視訊的詳細資訊,比如視訊時長等等!
2 你只是想訪問網路圖片並解析,而不想下載。
3 有諸如這種需求
下面直接說方法。
一,首先pom匯入架包
1 jave-core 必須引入
2 下面的只需要引入一個對應系統的就可以了。
<!-- jave 核心依賴 --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-core</artifactId> <version>2.4.6</version> </dependency> <!-- 根據不同作業系統引入不同FFmpeg包 --> <!-- window32位 FFmpeg --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-native-win32</artifactId> <version>2.4.6</version> </dependency> <!-- window64位 FFmpeg --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-native-win64</artifactId> <version>2.4.6</version> </dependency> <!-- linux64位 FFmpeg --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-native-linux64</artifactId> <version>2.4.6</version> </dependency> <!-- macos64位 FFmpeg --> <dependency> <groupId>ws.schild</groupId> <artifactId>jave-native-osx64</artifactId> <version>2.4.6</version> </dependency>
二,建立檔案
看一下包名和位置!重要!不要修改!
三,FFmpegFileInfo 程式碼
主要拷貝MultimediaInfo 並修改getInfo方法
package ws.schild.jave; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @description : * @auther Tyler * @date 2021/8/17 */ public class FFmpegFileInfo { private final static Log LOG = LogFactory.getLog(MultimediaObject.class); /** * This regexp is used to parse the ffmpeg output about the size of a video * stream. */ private static final Pattern SIZE_PATTERN = Pattern.compile( "(\\d+)x(\\d+)", Pattern.CASE_INSENSITIVE); /** * This regexp is used to parse the ffmpeg output about the frame rate value * of a video stream. */ private static final Pattern FRAME_RATE_PATTERN = Pattern.compile( "([\\d.]+)\\s+(?:fps|tbr)", Pattern.CASE_INSENSITIVE); /** * This regexp is used to parse the ffmpeg output about the bit rate value * of a stream. */ private static final Pattern BIT_RATE_PATTERN = Pattern.compile( "(\\d+)\\s+kb/s", Pattern.CASE_INSENSITIVE); /** * This regexp is used to parse the ffmpeg output about the sampling rate of * an audio stream. */ private static final Pattern SAMPLING_RATE_PATTERN = Pattern.compile( "(\\d+)\\s+Hz", Pattern.CASE_INSENSITIVE); /** * This regexp is used to parse the ffmpeg output about the channels number * of an audio stream. */ private static final Pattern CHANNELS_PATTERN = Pattern.compile( "(mono|stereo|quad)", Pattern.CASE_INSENSITIVE); /** * The locator of the ffmpeg executable used by this extractor. */ private final FFMPEGLocator locator; private File inputFile; /** * It builds an extractor using a {@link DefaultFFMPEGLocator} instance to * locate the ffmpeg executable to use. * * @param input Input file for creating MultimediaObject */ public FFmpegFileInfo(File input) { this.locator = new DefaultFFMPEGLocator(); this.inputFile = input; } public File getFile() { return this.inputFile; } public void setFile(File file) { this.inputFile = file; } /** * It builds an extractor with a custom {@link FFMPEGLocator}. * * @param input Input file for creating MultimediaObject * @param locator The locator picking up the ffmpeg executable used by the * extractor. */ public FFmpegFileInfo(File input, FFMPEGLocator locator) { this.locator = locator; this.inputFile = input; } /** * Returns a set informations about a multimedia file, if its format is * supported for decoding. * * @return A set of informations about the file and its contents. * @throws InputFormatException If the format of the source file cannot be * recognized and decoded. * @throws EncoderException If a problem occurs calling the underlying * ffmpeg executable. */ public MultimediaInfo getInfo(String url) throws InputFormatException, EncoderException { FFMPEGExecutor ffmpeg = locator.createExecutor(); ffmpeg.addArgument("-i"); ffmpeg.addArgument(url); try { ffmpeg.execute(); } catch (IOException e) { throw new EncoderException(e); } try { RBufferedReader reader = new RBufferedReader(new InputStreamReader(ffmpeg .getErrorStream())); return parseMultimediaInfo(inputFile, reader); } finally { ffmpeg.destroy(); } } /** * Private utility. It parses the ffmpeg output, extracting informations * about a source multimedia file. * * @param source The source multimedia file. * @param reader The ffmpeg output channel. * @return A set of informations about the source multimedia file and its * contents. * @throws InputFormatException If the format of the source file cannot be * recognized and decoded. * @throws EncoderException If a problem occurs calling the underlying * ffmpeg executable. */ private MultimediaInfo parseMultimediaInfo(File source, RBufferedReader reader) throws InputFormatException, EncoderException { Pattern p1 = Pattern.compile("^\\s*Input #0, (\\w+).+$\\s*", Pattern.CASE_INSENSITIVE); Pattern p2 = Pattern.compile( "^\\s*Duration: (\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d\\d).*$", Pattern.CASE_INSENSITIVE); Pattern p3 = Pattern.compile( "^\\s*Stream #\\S+: ((?:Audio)|(?:Video)|(?:Data)): (.*)\\s*$", Pattern.CASE_INSENSITIVE); Pattern p4 = Pattern.compile( "^\\s*Metadata:", Pattern.CASE_INSENSITIVE); MultimediaInfo info = null; try { int step = 0; while (true) { String line = reader.readLine(); LOG.debug("Output line: " + line); if (line == null) { break; } switch (step) { case 0: { String token = source.getAbsolutePath() + ": "; if (line.startsWith(token)) { String message = line.substring(token.length()); throw new InputFormatException(message); } Matcher m = p1.matcher(line); if (m.matches()) { String format = m.group(1); info = new MultimediaInfo(); info.setFormat(format); step++; } break; } case 1: { Matcher m = p2.matcher(line); if (m.matches()) { long hours = Integer.parseInt(m.group(1)); long minutes = Integer.parseInt(m.group(2)); long seconds = Integer.parseInt(m.group(3)); long dec = Integer.parseInt(m.group(4)); long duration = (dec * 10L) + (seconds * 1000L) + (minutes * 60L * 1000L) + (hours * 60L * 60L * 1000L); info.setDuration(duration); step++; } else { // step = 3; } break; } case 2: { Matcher m = p3.matcher(line); Matcher m4 = p4.matcher(line); if (m.matches()) { String type = m.group(1); String specs = m.group(2); if ("Video".equalsIgnoreCase(type)) { VideoInfo video = new VideoInfo(); StringTokenizer st = new StringTokenizer(specs, ","); for (int i = 0; st.hasMoreTokens(); i++) { String token = st.nextToken().trim(); if (i == 0) { video.setDecoder(token); } else { boolean parsed = false; // Video size. Matcher m2 = SIZE_PATTERN.matcher(token); if (!parsed && m2.find()) { int width = Integer.parseInt(m2 .group(1)); int height = Integer.parseInt(m2 .group(2)); video.setSize(new VideoSize(width, height)); parsed = true; } // Frame rate. m2 = FRAME_RATE_PATTERN.matcher(token); if (!parsed && m2.find()) { try { float frameRate = Float .parseFloat(m2.group(1)); video.setFrameRate(frameRate); } catch (NumberFormatException e) { LOG.info("Invalid frame rate value: " + m2.group(1), e); } parsed = true; } // Bit rate. m2 = BIT_RATE_PATTERN.matcher(token); if (!parsed && m2.find()) { int bitRate = Integer.parseInt(m2 .group(1)); video.setBitRate(bitRate*1000); parsed = true; } } } info.setVideo(video); } else if ("Audio".equalsIgnoreCase(type)) { AudioInfo audio = new AudioInfo(); StringTokenizer st = new StringTokenizer(specs, ","); for (int i = 0; st.hasMoreTokens(); i++) { String token = st.nextToken().trim(); if (i == 0) { audio.setDecoder(token); } else { boolean parsed = false; // Sampling rate. Matcher m2 = SAMPLING_RATE_PATTERN .matcher(token); if (!parsed && m2.find()) { int samplingRate = Integer.parseInt(m2 .group(1)); audio.setSamplingRate(samplingRate); parsed = true; } // Channels. m2 = CHANNELS_PATTERN.matcher(token); if (!parsed && m2.find()) { String ms = m2.group(1); if ("mono".equalsIgnoreCase(ms)) { audio.setChannels(1); } else if ("stereo" .equalsIgnoreCase(ms)) { audio.setChannels(2); } else if ("quad" .equalsIgnoreCase(ms)) { audio.setChannels(4); } parsed = true; } // Bit rate. m2 = BIT_RATE_PATTERN.matcher(token); if (!parsed && m2.find()) { int bitRate = Integer.parseInt(m2 .group(1)); audio.setBitRate(bitRate*1000); parsed = true; } } } info.setAudio(audio); } } else // if (m4.matches()) { // Stay on level 2 } /* else { step = 3; } */ break; } default: break; } if (line.startsWith("frame=")) { reader.reinsertLine(line); break; } } } catch (IOException e) { throw new EncoderException(e); } if (info == null) { throw new InputFormatException(); } return info; } }
四,測試
測試程式碼:
String url="https://10years-qa.oss-cn-hangzhou.aliyuncs.com/234.mp4"; File mediaFile = new File(url); FFmpegFileInfo ffmpegFileInfo = new FFmpegFileInfo(mediaFile); MultimediaInfo info = null; info = ffmpegFileInfo.getInfo(url); long duration = info.getDuration();
效果: