diff --git a/lib/jna.jar b/lib/jna.jar new file mode 100644 index 00000000..33461ecf Binary files /dev/null and b/lib/jna.jar differ diff --git a/source/net/sourceforge/filebot/mediainfo/MediaInfo.java b/source/net/sourceforge/filebot/mediainfo/MediaInfo.java new file mode 100644 index 00000000..113bfa8b --- /dev/null +++ b/source/net/sourceforge/filebot/mediainfo/MediaInfo.java @@ -0,0 +1,228 @@ + +package net.sourceforge.filebot.mediainfo; + + +import java.io.Closeable; +import java.io.File; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import com.sun.jna.Pointer; +import com.sun.jna.WString; + + +public class MediaInfo implements Closeable { + + private Pointer handle; + + + public MediaInfo() { + handle = MediaInfoLibrary.INSTANCE.New(); + } + + + public boolean open(File file) { + return MediaInfoLibrary.INSTANCE.Open(handle, new WString(file.getPath())) > 0; + } + + + public String inform() { + return MediaInfoLibrary.INSTANCE.Inform(handle).toString(); + } + + + public String option(String option) { + return option(option, ""); + } + + + public String option(String option, String value) { + return MediaInfoLibrary.INSTANCE.Option(handle, new WString(option), new WString(value)).toString(); + } + + + public String get(StreamKind streamKind, int streamNumber, String parameter) { + return get(streamKind, streamNumber, parameter, InfoKind.Text, InfoKind.Name); + } + + + public String get(StreamKind streamKind, int streamNumber, String parameter, InfoKind infoKind) { + return get(streamKind, streamNumber, parameter, infoKind, InfoKind.Name); + } + + + public String get(StreamKind streamKind, int streamNumber, String parameter, InfoKind infoKind, InfoKind searchKind) { + return MediaInfoLibrary.INSTANCE.Get(handle, streamKind.ordinal(), streamNumber, new WString(parameter), infoKind.ordinal(), searchKind.ordinal()).toString(); + } + + + public String get(StreamKind streamKind, int streamNumber, int parameterIndex) { + return get(streamKind, streamNumber, parameterIndex, InfoKind.Text); + } + + + public String get(StreamKind streamKind, int streamNumber, int parameterIndex, InfoKind infoKind) { + return MediaInfoLibrary.INSTANCE.GetI(handle, streamKind.ordinal(), streamNumber, parameterIndex, infoKind.ordinal()).toString(); + } + + + public int streamCount(StreamKind streamKind) { + return MediaInfoLibrary.INSTANCE.Count_Get(handle, streamKind.ordinal(), -1); + } + + + public int parameterCount(StreamKind streamKind, int streamNumber) { + return MediaInfoLibrary.INSTANCE.Count_Get(handle, streamKind.ordinal(), streamNumber); + } + + + public Map>> snapshot() { + Map>> mediaInfo = new EnumMap>>(StreamKind.class); + + for (StreamKind streamKind : StreamKind.values()) { + int streamCount = streamCount(streamKind); + + if (streamCount > 0) { + List> streamInfoList = new ArrayList>(streamCount); + + for (int i = 0; i < streamCount; i++) { + streamInfoList.add(snapshot(streamKind, i)); + } + + mediaInfo.put(streamKind, streamInfoList); + } + } + + return mediaInfo; + } + + + public SortedMap snapshot(StreamKind streamKind, int streamNumber) { + TreeMap streamInfo = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + for (int i = 0, count = parameterCount(streamKind, streamNumber); i < count; i++) { + String value = get(streamKind, streamNumber, i, InfoKind.Text); + + if (value.length() > 0) { + streamInfo.put(get(streamKind, streamNumber, i, InfoKind.Name), value); + } + } + + return streamInfo; + } + + + @Override + public void close() { + MediaInfoLibrary.INSTANCE.Close(handle); + } + + + public void dispose() { + if (handle == null) + throw new IllegalStateException(); + + MediaInfoLibrary.INSTANCE.Delete(handle); + handle = null; + } + + + @Override + protected void finalize() throws Throwable { + if (handle != null) { + dispose(); + } + } + + + public enum StreamKind { + General, + Video, + Audio, + Text, + Chapters, + Image, + Menu; + } + + + public enum InfoKind { + /** + * Unique name of parameter. + */ + Name, + + /** + * Value of parameter. + */ + Text, + + /** + * Unique name of measure unit of parameter. + */ + Measure, + + Options, + + /** + * Translated name of parameter. + */ + Name_Text, + + /** + * Translated name of measure unit. + */ + Measure_Text, + + /** + * More information about the parameter. + */ + Info, + + /** + * How this parameter is supported, could be N (No), B (Beta), R (Read only), W + * (Read/Write). + */ + HowTo, + + /** + * Domain of this piece of information. + */ + Domain; + } + + + public static String version() { + return staticOption("Info_Version"); + } + + + public static String parameters() { + return staticOption("Info_Parameters"); + } + + + public static String codecs() { + return staticOption("Info_Codecs"); + } + + + public static String capacities() { + return staticOption("Info_Capacities"); + } + + + public static String staticOption(String option) { + return staticOption(option, ""); + } + + + public static String staticOption(String option, String value) { + return MediaInfoLibrary.INSTANCE.Option(null, new WString(option), new WString(value)).toString(); + } + +} diff --git a/source/net/sourceforge/filebot/mediainfo/MediaInfoLibrary.java b/source/net/sourceforge/filebot/mediainfo/MediaInfoLibrary.java new file mode 100644 index 00000000..516405c3 --- /dev/null +++ b/source/net/sourceforge/filebot/mediainfo/MediaInfoLibrary.java @@ -0,0 +1,125 @@ + +package net.sourceforge.filebot.mediainfo; + + +import static java.util.Collections.singletonMap; + +import java.lang.reflect.Method; + +import com.sun.jna.FunctionMapper; +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.NativeLibrary; +import com.sun.jna.Pointer; +import com.sun.jna.WString; + + +interface MediaInfoLibrary extends Library { + + MediaInfoLibrary INSTANCE = (MediaInfoLibrary) Native.loadLibrary("mediainfo", MediaInfoLibrary.class, singletonMap(OPTION_FUNCTION_MAPPER, new FunctionMapper() { + + @Override + public String getFunctionName(NativeLibrary lib, Method method) { + // MediaInfo_New(), MediaInfo_Open() ... + return "MediaInfo_" + method.getName(); + } + })); + + + /** + * Create a new handle. + * + * @return handle + */ + Pointer New(); + + + /** + * Open a file and collect information about it (technical information and tags). + * + * @param handle + * @param file full name of the file to open + * @return 1 if file was opened, 0 if file was not not opened + */ + int Open(Pointer handle, WString file); + + + /** + * Configure or get information about MediaInfo. + * + * @param handle + * @param option The name of option + * @param value The value of option + * @return Depends on the option: by default "" (nothing) means No, other means Yes + */ + WString Option(Pointer handle, WString option, WString value); + + + /** + * Get all details about a file. + * + * @param handle + * @return All details about a file in one string + */ + WString Inform(Pointer handle); + + + /** + * Get a piece of information about a file (parameter is a string). + * + * @param handle + * @param streamKind Kind of stream (general, video, audio...) + * @param streamNumber Stream number in Kind of stream (first, second...) + * @param parameter Parameter you are looking for in the stream (Codec, width, bitrate...), + * in string format ("Codec", "Width"...) + * @param infoKind Kind of information you want about the parameter (the text, the measure, + * the help...) + * @param searchKind Where to look for the parameter + * @return a string about information you search, an empty string if there is a problem + */ + WString Get(Pointer handle, int streamKind, int streamNumber, WString parameter, int infoKind, int searchKind); + + + /** + * Get a piece of information about a file (parameter is an integer). + * + * @param handle + * @param streamKind Kind of stream (general, video, audio...) + * @param streamNumber Stream number in Kind of stream (first, second...) + * @param parameter Parameter you are looking for in the stream (Codec, width, bitrate...), + * in integer format (first parameter, second parameter...) + * @param infoKind Kind of information you want about the parameter (the text, the measure, + * the help...) + * @return a string about information you search, an empty string if there is a problem + */ + WString GetI(Pointer handle, int streamKind, int streamNumber, int parameterIndex, int infoKind); + + + /** + * Count of streams of a stream kind (StreamNumber not filled), or count of piece of + * information in this stream. + * + * @param handle + * @param streamKind Kind of stream (general, video, audio...) + * @param streamNumber Stream number in this kind of stream (first, second...) + * @return number of streams of the given stream kind + */ + int Count_Get(Pointer handle, int streamKind, int streamNumber); + + + /** + * Close a file opened before with Open(). + * + * @param handle + */ + void Close(Pointer handle); + + + /** + * Dispose of a handle created with New(). + * + * @param handle + */ + void Delete(Pointer handle); + +}