diff --git a/lib/native/mac-x86_64/libmediainfo.dylib b/lib/native/mac-x86_64/libmediainfo.dylib old mode 100644 new mode 100755 index d5135544..8e06487e Binary files a/lib/native/mac-x86_64/libmediainfo.dylib and b/lib/native/mac-x86_64/libmediainfo.dylib differ diff --git a/source/net/filebot/mediainfo/MediaInfo.java b/source/net/filebot/mediainfo/MediaInfo.java index 620d5bf5..6e0c652d 100644 --- a/source/net/filebot/mediainfo/MediaInfo.java +++ b/source/net/filebot/mediainfo/MediaInfo.java @@ -3,6 +3,7 @@ package net.filebot.mediainfo; import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.ArrayList; @@ -10,6 +11,7 @@ import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.logging.Logger; import com.sun.jna.NativeLibrary; import com.sun.jna.Platform; @@ -42,17 +44,50 @@ public class MediaInfo implements Closeable { } public synchronized boolean open(File file) { - if (!file.isFile()) + if (!file.isFile()) { return false; - - // MacOS filesystem may require NFD unicode decomposition (forcing NFD seems to work for System.out() but passing to libmediainfo is still not working) - String path = file.getAbsolutePath(); - if (Platform.isMac()) { - path = Normalizer.normalize(path, Form.NFD); } + + String path = file.getAbsolutePath(); + + // on Mac files that contain accents cannot be opened via JNA WString file paths due to encoding differences so we use the buffer interface instead for these files + if (Platform.isMac() && path.length() != Normalizer.normalize(path, Form.NFD).length()) { + try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { + return openViaBuffer(raf); + } catch (IOException e) { + return false; + } + } + return MediaInfoLibrary.INSTANCE.Open(handle, new WString(path)) > 0; } + private boolean openViaBuffer(RandomAccessFile f) throws IOException { + byte[] buffer = new byte[64 * 1024]; + int read = -1; + + if (MediaInfoLibrary.INSTANCE.Open_Buffer_Init(handle, f.length(), 0) <= 0) { + return false; + } + + do { + read = f.read(buffer); + int result = MediaInfoLibrary.INSTANCE.Open_Buffer_Continue(handle, buffer, read); + if ((result & 8) == 8) { + break; + } + + if (MediaInfoLibrary.INSTANCE.Open_Buffer_Continue_GoTo_Get(handle) != -1) { + long gotoPos = MediaInfoLibrary.INSTANCE.Open_Buffer_Continue_GoTo_Get(handle); + f.seek(gotoPos); + MediaInfoLibrary.INSTANCE.Open_Buffer_Init(handle, f.length(), gotoPos); + } + } while (read > 0); + + MediaInfoLibrary.INSTANCE.Open_Buffer_Finalize(handle); + return true; + } + public synchronized String inform() { return MediaInfoLibrary.INSTANCE.Inform(handle).toString(); } diff --git a/source/net/filebot/mediainfo/MediaInfoLibrary.java b/source/net/filebot/mediainfo/MediaInfoLibrary.java index fb5af5b5..0fed1061 100644 --- a/source/net/filebot/mediainfo/MediaInfoLibrary.java +++ b/source/net/filebot/mediainfo/MediaInfoLibrary.java @@ -1,7 +1,5 @@ - package net.filebot.mediainfo; - import static java.util.Collections.*; import java.lang.reflect.Method; @@ -13,47 +11,45 @@ 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 + * @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 + * @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. @@ -62,50 +58,52 @@ interface MediaInfoLibrary extends Library { * @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 + * @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...) + * @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. + * 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...) + * @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(). @@ -113,7 +111,6 @@ interface MediaInfoLibrary extends Library { * @param handle */ void Close(Pointer handle); - /** * Dispose of a handle created with New(). @@ -121,5 +118,25 @@ interface MediaInfoLibrary extends Library { * @param handle */ void Delete(Pointer handle); - + + /** + * Open_Buffer_Init + */ + int Open_Buffer_Init(Pointer handle, long length, long offset); + + /** + * Open_Buffer_Continue + */ + int Open_Buffer_Continue(Pointer handle, byte[] buffer, int size); + + /** + * Open_Buffer_Continue_GoTo_Get + */ + long Open_Buffer_Continue_GoTo_Get(Pointer handle); + + /** + * Open_Buffer_Finalize + */ + int Open_Buffer_Finalize(Pointer handle); + }