1 /** 2 * Object oriented wrapper for $(LINK2 http://mediainfo.sourceforge.net/Support/SDK, MediaInfo) 3 * License: 4 * This wrapper $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 5 * MediaInfo $(LINK2 http://www.gnu.org/licenses/lgpl-3.0.txt, LGPL 3.0) 6 * Authors: Johannes Pfau, Carsten Schlote 7 */ 8 module mediainfo; 9 10 import std.string; 11 import std.conv; 12 import std.typecons; 13 14 import mediainfodll; 15 16 //public alias MediaInfo_stream_t Stream; 17 //public alias MediaInfo_info_t Info; 18 19 /** A exception of the mediainfo wrapper */ 20 public class MediaInfoException : Exception 21 { 22 public this(string msg) 23 { 24 super(msg); 25 } 26 } 27 28 /** This is the UTF Wrapper for libmediainfo */ 29 public struct MediaInfo 30 { 31 private: 32 struct Payload 33 { 34 void* _payload; 35 this(void* h) 36 { 37 _payload = h; 38 } 39 ~this() 40 { 41 if(_payload) 42 { 43 mediainfo_FunctionTable.MediaInfo_Delete(_payload); 44 _payload = null; 45 MediaInfoDLL_UnLoad(); 46 } 47 } 48 // Should never perform these operations 49 this(this) { assert(false); } 50 void opAssign(MediaInfo.Payload rhs) { assert(false); } 51 } 52 53 alias Data = RefCounted!(Payload, RefCountedAutoInitialize.no); 54 Data _data; 55 56 @property void* handle() 57 { 58 return _data._payload; 59 } 60 61 public: 62 63 /** Use call operator to initialize resource */ 64 static MediaInfo opCall() 65 { 66 MediaInfo info; 67 auto rc = MediaInfoDLL_Load(); 68 if(rc != 1) { 69 throw new MediaInfoException("Couldn't open mediainfo library"); 70 } 71 72 auto h = mediainfo_FunctionTable.MediaInfo_New(); 73 info._data.refCountedStore.ensureInitialized(); 74 info._data._payload = h; 75 return info; 76 } 77 78 /** 79 * Open a file. 80 * Open a file and collect information about it (technical information and tags) 81 * 82 * Parameters: 83 * fileName = Full name of file to open 84 */ 85 void open(string fileName) 86 { 87 version(Workaround_UTF_Bug) { 88 import std.stdio : File; 89 auto fh = File(fileName); 90 scope(exit) fh.close; 91 this.openBufferInit(fh.size, 0); 92 93 //The parsing loop 94 ubyte[4096] rawbuffer; 95 ubyte[] buffer; 96 do 97 { 98 // Read some data to buffer... 99 buffer = fh.rawRead(rawbuffer); 100 // Sending the buffer to MediaInfo 101 auto status = this.openBufferContinue(buffer.ptr, buffer.length); 102 if (status&0x08) //Bit3=Finished 103 break; 104 // Testing if there is a MediaInfo request to go elsewhere 105 if (this.openBufferContinueGoToGet() != -1 ) 106 { 107 // Position the file 108 import core.stdc.stdio : SEEK_SET; 109 fh.seek(this.openBufferContinueGoToGet(), SEEK_SET); 110 // Informing MediaInfo we have seek 111 this.openBufferInit(fh.size, fh.tell); 112 } 113 } 114 while (buffer.length > 0); 115 //This is the end of the stream, MediaInfo must finnish some work 116 this.openBufferFinalize(); 117 } 118 else { 119 static MediaInfo_Char* _fileNameRef; 120 import std.utf; 121 auto filename = fileName.toUTFz!(MediaInfo_Char*); 122 auto rc = mediainfo_FunctionTable.MediaInfo_Open(handle, filename); 123 if(!rc) 124 { 125 throw new MediaInfoException("Couldn't open file: " ~ fileName); 126 } 127 _fileNameRef = fileName; 128 } 129 } 130 /+ /** 131 * Open a buffer. 132 * Open a Buffer (Begin and end of the stream) and collect information about it (technical information and tags) 133 * Params: 134 * begin = First bytes of the buffer 135 * begin_size = Size of Begin 136 * end = Last bytes of the buffer 137 * end_size = Size of End 138 * file_size = Total size of the file 139 */ 140 void open(ubyte* begin, size_t begin_size, ubyte* end, size_t end_size) 141 { 142 if(MediaInfo_Open_Buffer(handle, begin, begin_size, end, end_size)) 143 { 144 throw new MediaInfoException("Couldn't open file from buffer"); 145 } 146 } 147 +/ 148 /** 149 * Open a stream (Init). 150 * 151 * Open a stream and collect information about it (technical information and tags) 152 * 153 * Params: 154 * fileSize = Estimated file size 155 * fileOffset = Offset of the file (if we don't have the beginning of the file) 156 */ 157 size_t openBufferInit(long fileSize = -1, long fileOffset = 0) 158 { 159 return mediainfo_FunctionTable.MediaInfo_Open_Buffer_Init(handle, fileSize, fileOffset); 160 } 161 /** 162 * Open a stream (Continue). 163 * 164 * Open a stream and collect information about it (technical information and tags) 165 * 166 * Params: 167 * buffer = pointer to the stream 168 * size =Count of bytes to read 169 */ 170 size_t openBufferContinue(ubyte* buffer, size_t size) 171 { 172 return mediainfo_FunctionTable.MediaInfo_Open_Buffer_Continue(handle, buffer, size); 173 } 174 /** 175 * Open a stream (Get the needed file Offset). 176 * 177 * Open a stream and collect information about it (technical information and tags) 178 * 179 * Returns: 180 * the needed offset of the file 181 * File size if no more bytes are needed 182 */ 183 long openBufferContinueGoToGet() 184 { 185 return mediainfo_FunctionTable.MediaInfo_Open_Buffer_Continue_GoTo_Get(handle); 186 } 187 /** 188 * Open a stream (Finalize). 189 * 190 * Open a stream and collect information about it (technical information and tags) 191 */ 192 size_t openBufferFinalize() 193 { 194 return mediainfo_FunctionTable.MediaInfo_Open_Buffer_Finalize(handle); 195 } 196 /+ /** 197 * (NOT IMPLEMENTED YET) Save the file 198 * 199 * (NOT IMPLEMENTED YET) Save the file opened before with Open() (modifications of tags) 200 */ 201 void save() 202 { 203 if(mediainfo_FunctionTable.MediaInfo_Save(handle)) 204 { 205 throw new MediaInfoException("Couldn't save file"); 206 } 207 } 208 +/ 209 /** 210 * Close a file. 211 * 212 * Close a file opened before with Open() (without saving) 213 * 214 * Warning: 215 * without have saved before, modifications are lost 216 */ 217 void close() 218 { 219 mediainfo_FunctionTable.MediaInfo_Close(handle); 220 version(Workaround_UTF_Bug) {} else _fileNameRef = null; 221 } 222 /** 223 * String MediaInfoLib::MediaInfo::Inform ( size_t Reserved = 0 ) 224 * Get all details about a file. 225 * 226 * Get all details about a file in one string 227 * 228 * Precondition: 229 * You can change default presentation with Inform_Set() 230 */ 231 string inform(size_t reserved = 0) 232 { 233 import std.utf; 234 auto strptr = mediainfo_FunctionTable.MediaInfo_Inform(handle, reserved); 235 auto str = strptr.fromStringz; 236 return to!string(str); 237 } 238 /** 239 * Get a piece of information about a file (parameter is an integer). 240 * 241 * Get a piece of information about a file (parameter is an integer) 242 * 243 * Params: 244 * streamKind = Kind of stream (general, video, audio...) 245 * streamNumber = Stream number in Kind of stream (first, second...) 246 * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in integer format (first parameter, second parameter...) 247 * infoKind = Kind of information you want about the parameter (the text, the measure, the help...) 248 * Returns: 249 * a string about information you search 250 * an empty string if there is a problem 251 */ 252 string get(MediaInfo_stream_t streamKind, size_t streamNumber, size_t parameter, 253 MediaInfo_info_t infoKind = MediaInfo_info_t.MediaInfo_Info_Text) 254 { 255 import std.utf; 256 auto strptr = mediainfo_FunctionTable.MediaInfo_GetI(handle, streamKind, streamNumber, 257 parameter, infoKind); 258 auto str = strptr.fromStringz; 259 return to!string(str); 260 } 261 /** 262 * Get a piece of information about a file (parameter is a string). 263 * 264 * Get a piece of information about a file (parameter is a string) 265 * 266 * Params: 267 * streamKind = Kind of stream (general, video, audio...) 268 * streamNumber = Stream number in Kind of stream (first, second...) 269 * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in string format ("Codec", "Width"...) 270 * See MediaInfo::Option("Info_Parameters") to have the full list 271 * infoKind = Kind of information you want about the parameter (the text, the measure, the help...) 272 * searchKind = Where to look for the parameter 273 * Returns: 274 * a string about information you search 275 * an empty string if there is a problem 276 */ 277 string get(MediaInfo_stream_t streamKind, size_t streamNumber, 278 string parameter, MediaInfo_info_t infoKind = MediaInfo_info_t.MediaInfo_Info_Text, 279 MediaInfo_info_t searchKind = MediaInfo_info_t.MediaInfo_Info_Name) 280 { 281 import std.utf; 282 MediaInfo_Char* parameterZ = parameter.toUTFz!(MediaInfo_Char*); 283 const auto strptr = mediainfo_FunctionTable.MediaInfo_Get(handle, streamKind, streamNumber, parameterZ, infoKind, searchKind); 284 auto str = strptr.fromStringz; 285 return to!string(str); 286 } 287 /+ /** 288 * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is an int) 289 * 290 * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is an integer) 291 * 292 * Warning: 293 * Not yet implemented, do not use it 294 * Params: 295 * toSet = Piece of information 296 * streamKind = Kind of stream (general, video, audio...) 297 * streamNumber = Stream number in Kind of stream (first, second...) 298 * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in integer format (first parameter, second parameter...) 299 * oldValue = The old value of the parameter 300 * if OldValue is empty and ToSet is filled: tag is added 301 * if OldValue is filled and ToSet is filled: tag is replaced 302 * if OldValue is filled and ToSet is empty: tag is deleted 303 */ 304 void set(const(string) toSet, Stream streamKind, size_t streamNumber, 305 size_t parameter, const(string) oldValue = "") 306 { 307 if(!mediainfo_FunctionTable.MediaInfo_SetI(handle, toStringz(toSet), streamKind, streamNumber, 308 parameter, toStringz(oldValue))) 309 { 310 throw new MediaInfoException("Couldn't set parameter"); 311 } 312 } 313 /** 314 * (NOT IMPLEMENTED YET) Set information about a file (parameter is a string) 315 * 316 * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is a string) 317 * 318 * Warning: 319 * Not yet implemented, do not use it 320 * Params: 321 * toSet = Piece of information 322 * streamKind = Kind of stream (general, video, audio...) 323 * streamNumber = Stream number in Kind of stream (first, second...) 324 * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in string format 325 * oldValue = The old value of the parameter 326 * if OldValue is empty and ToSet is filled: tag is added 327 * if OldValue is filled and ToSet is filled: tag is replaced 328 * if OldValue is filled and ToSet is empty: tag is deleted 329 */ 330 void set(const(string) toSet, Stream streamKind, size_t streamNumber, 331 const(string) parameter, const(string) oldValue = "") 332 { 333 if(!mediainfo_FunctionTable.MediaInfo_Set(handle, toStringz(toSet), streamKind, streamNumber, 334 toStringz(parameter), toStringz(oldValue))) 335 { 336 throw new MediaInfoException("Couldn't set parameter"); 337 } 338 } 339 +/ 340 /** 341 * Output the written size when "File_Duplicate" option is used. 342 * 343 * Output the written size when "File_Duplicate" option is used. 344 * 345 * Params: 346 * value = The unique name of the duplicated stream (begin with "memory://") 347 * Returns: 348 * The size of the used buffer 349 */ 350 size_t outputBufferGet(const(string) value) 351 { 352 import std.utf; 353 MediaInfo_Char* valueZ = value.toUTFz!(MediaInfo_Char*); 354 return mediainfo_FunctionTable.MediaInfo_Output_Buffer_Get(handle, valueZ); 355 } 356 /** 357 * Output the written size when "File_Duplicate" option is used. 358 * 359 * Output the written size when "File_Duplicate" option is used. 360 * 361 * Params: 362 * pos = The position ? 363 * Returns: 364 * The size of the used buffer 365 */ 366 size_t outputBufferGet(size_t pos) 367 { 368 return mediainfo_FunctionTable.MediaInfo_Output_Buffer_GetI(handle, pos); 369 } 370 /** 371 * Configure or get information about MediaInfoLib 372 * 373 * Params: 374 * option = The name of option 375 * value = The value of option 376 * Returns: 377 * Depend of the option: by default "" (nothing) means No, other means Yes 378 */ 379 string option(const(string) option, const(string) value = "") 380 { 381 import std.utf; 382 MediaInfo_Char* optionZ = option.toUTFz!(MediaInfo_Char*); 383 MediaInfo_Char* valueZ = value.toUTFz!(MediaInfo_Char*); 384 auto strptr = mediainfo_FunctionTable.MediaInfo_Option(handle, optionZ, valueZ); 385 auto str = strptr.fromStringz; 386 return to!string(str); 387 } 388 389 /* 390 static string optionStatic(const(string) option, const(string) value = "") 391 { 392 return to!string(mediainfo_FunctionTable.MediaInfo_Option_Static(handle, toStringz(option), toStringz(value))); 393 }*/ 394 395 /** 396 * (NOT IMPLEMENTED YET) Get the state of the library 397 * 398 * Return values: 399 * <1000 No information is available for the file yet 400 * >=1000_<5000 Only local (into the file) information is available, getting Internet information (titles only) is no finished yet 401 * 5000 (only if Internet connection is accepted) User interaction is needed (use Option() with "Internet_Title_Get") 402 * Warning: even there is only one possible, user interaction (or the software) is needed 403 * >5000<=10000 Only local (into the file) information is available, getting Internet information (all) is no finished yet 404 * <10000 Done 405 */ 406 size_t getState() 407 { 408 return mediainfo_FunctionTable.MediaInfo_State_Get(handle); 409 } 410 /** 411 * Count of streams of a stream kind (StreamNumber not filled), or count of piece of information in this stream. 412 * 413 * Params: 414 * streamKind = Kind of stream (general, video, audio...) 415 * streamNumber = Stream number in this kind of stream (first, second...) 416 */ 417 size_t getCount(MediaInfo_stream_t streamKind, size_t streamNumber = -1) 418 { 419 return mediainfo_FunctionTable.MediaInfo_Count_Get(handle, streamKind, streamNumber); 420 } 421 }