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 ///
20 public class MediaInfoException : Exception
21 {
22     public this(string msg)
23     {
24         super(msg);
25     }
26 }
27 
28 ///
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                     MediaInfoA_Delete(_payload);
44                     _payload = null;
45                 }
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         /** Use call operator to initialize resource */
63         static MediaInfo opCall()
64         {
65             MediaInfo info;
66             auto h = MediaInfoA_New();
67             info._data.refCountedStore.ensureInitialized();
68             info._data._payload = h;
69             return info;
70         }
71 
72         /**
73          * Open a file.
74          * Open a file and collect information about it (technical information and tags)
75          *
76          * Parameters:
77          * fileName = Full name of file to open
78          */
79         void open(string fileName)
80         {
81             if(!MediaInfoA_Open(handle, toStringz(fileName)))
82             {
83                 throw new MediaInfoException("Couldn't open file: " ~ fileName);
84             }
85         }
86 /+        /**
87          * Open a buffer.
88          * Open a Buffer (Begin and end of the stream) and collect information about it (technical information and tags)
89          * Params:
90          * begin = First bytes of the buffer
91          * begin_size = Size of Begin
92          * end = Last bytes of the buffer
93          * end_size = Size of End
94          * file_size = Total size of the file
95          */
96         void open(ubyte* begin, size_t begin_size, ubyte* end, size_t end_size)
97         {
98             if(MediaInfo_Open_Buffer(handle, begin, begin_size, end, end_size))
99             {
100                 throw new MediaInfoException("Couldn't open file from buffer");
101             }
102         }
103 +/
104         /**
105          * Open a stream (Init).
106          *
107          * Open a stream and collect information about it (technical information and tags)
108          *
109          * Params:
110          * fileSize = Estimated file size
111          * fileOffset = Offset of the file (if we don't have the beginning of the file)
112          */
113         size_t openBufferInit(long fileSize = -1, long fileOffset = 0)
114         {
115             return MediaInfoA_Open_Buffer_Init(handle, fileSize, fileOffset);
116         }
117         /**
118          * Open a stream (Continue).
119          *
120          * Open a stream and collect information about it (technical information and tags)
121          *
122          * Params:
123          * buffer = pointer to the stream
124          * size =Count of bytes to read
125          */
126         size_t openBufferContinue(ubyte* buffer, size_t size)
127         {
128             return MediaInfoA_Open_Buffer_Continue(handle, buffer, size);
129         }
130         /**
131          * Open a stream (Get the needed file Offset).
132          *
133          * Open a stream and collect information about it (technical information and tags)
134          *
135          * Returns:
136          * the needed offset of the file
137          * File size if no more bytes are needed
138          */
139         long openBufferContinueGoToGet()
140         {
141             return MediaInfoA_Open_Buffer_Continue_GoTo_Get(handle);
142         }
143         /**
144          * Open a stream (Finalize).
145          *
146          * Open a stream and collect information about it (technical information and tags)
147          */
148         size_t openBufferFinalize()
149         {
150             return MediaInfoA_Open_Buffer_Finalize(handle);
151         }
152 /+        /**
153          * (NOT IMPLEMENTED YET) Save the file
154          *
155          * (NOT IMPLEMENTED YET) Save the file opened before with Open() (modifications of tags)
156          */
157         void save()
158         {
159             if(MediaInfo_Save(handle))
160             {
161                 throw new MediaInfoException("Couldn't save file");
162             }
163         }
164 +/
165         /**
166          * Close a file.
167          *
168          * Close a file opened before with Open() (without saving)
169          *
170          * Warning:
171          * without have saved before, modifications are lost
172          */
173         void close()
174         {
175             MediaInfoA_Close(handle);
176         }
177         /**
178          * String MediaInfoLib::MediaInfo::Inform   (   size_t  Reserved = 0     )
179          * Get all details about a file.
180          *
181          * Get all details about a file in one string
182          *
183          * Precondition:
184          * You can change default presentation with Inform_Set()
185          */
186         string inform(size_t reserved = 0)
187         {
188             return to!string(MediaInfoA_Inform(handle, reserved));
189         }
190         /**
191          * Get a piece of information about a file (parameter is an integer).
192          *
193          * Get a piece of information about a file (parameter is an integer)
194          *
195          * Params:
196          * streamKind = Kind of stream (general, video, audio...)
197          * streamNumber = Stream number in Kind of stream (first, second...)
198          * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in integer format (first parameter, second parameter...)
199          * infoKind = Kind of information you want about the parameter (the text, the measure, the help...)
200          * Returns:
201          * a string about information you search
202          * an empty string if there is a problem
203          */
204         string get(MediaInfo_stream_t streamKind, size_t streamNumber, size_t parameter,
205             MediaInfo_info_t infoKind = MediaInfo_info_t.MediaInfo_Info_Text)
206         {
207             return to!string(MediaInfoA_GetI(handle, streamKind, streamNumber,
208                 parameter, infoKind));
209         }
210         /**
211          * Get a piece of information about a file (parameter is a string).
212          *
213          * Get a piece of information about a file (parameter is a string)
214          *
215          * Params:
216          * streamKind = Kind of stream (general, video, audio...)
217          * streamNumber = Stream number in Kind of stream (first, second...)
218          * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in string format ("Codec", "Width"...)
219          * See MediaInfo::Option("Info_Parameters") to have the full list
220          * infoKind = Kind of information you want about the parameter (the text, the measure, the help...)
221          * searchKind = Where to look for the parameter
222          * Returns:
223          * a string about information you search
224          * an empty string if there is a problem
225          */
226         string get(MediaInfo_stream_t streamKind, size_t streamNumber,
227             const(string) parameter, MediaInfo_info_t infoKind = MediaInfo_info_t.MediaInfo_Info_Text,
228             MediaInfo_info_t searchKind = MediaInfo_info_t.MediaInfo_Info_Name)
229         {
230             return to!string(MediaInfoA_Get(handle, streamKind, streamNumber, toStringz(parameter),
231                 infoKind, searchKind));
232         }
233 /+        /**
234          * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is an int)
235          *
236          * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is an integer)
237          *
238          * Warning:
239          * Not yet implemented, do not use it
240          * Params:
241          * toSet = Piece of information
242          * streamKind = Kind of stream (general, video, audio...)
243          * streamNumber = Stream number in Kind of stream (first, second...)
244          * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in integer format (first parameter, second parameter...)
245          * oldValue = The old value of the parameter
246          * if OldValue is empty and ToSet is filled: tag is added
247          * if OldValue is filled and ToSet is filled: tag is replaced
248          * if OldValue is filled and ToSet is empty: tag is deleted
249          */
250         void set(const(string) toSet, Stream streamKind, size_t streamNumber,
251             size_t parameter, const(string) oldValue = "")
252         {
253             if(!MediaInfo_SetI(handle, toStringz(toSet), streamKind, streamNumber,
254                 parameter, toStringz(oldValue)))
255             {
256                 throw new MediaInfoException("Couldn't set parameter");
257             }
258         }
259         /**
260          * (NOT IMPLEMENTED YET) Set information about a file (parameter is a string)
261          *
262          * (NOT IMPLEMENTED YET) Set a piece of information about a file (parameter is a string)
263          *
264          * Warning:
265          * Not yet implemented, do not use it
266          * Params:
267          * toSet = Piece of information
268          * streamKind = Kind of stream (general, video, audio...)
269          * streamNumber = Stream number in Kind of stream (first, second...)
270          * parameter = Parameter you are looking for in the stream (Codec, width, bitrate...), in string format
271          * oldValue = The old value of the parameter
272          * if OldValue is empty and ToSet is filled: tag is added
273          * if OldValue is filled and ToSet is filled: tag is replaced
274          * if OldValue is filled and ToSet is empty: tag is deleted
275          */
276         void set(const(string) toSet, Stream streamKind, size_t streamNumber,
277             const(string) parameter, const(string) oldValue = "")
278         {
279             if(!MediaInfo_Set(handle, toStringz(toSet), streamKind, streamNumber,
280                 toStringz(parameter), toStringz(oldValue)))
281             {
282                 throw new MediaInfoException("Couldn't set parameter");
283             }
284         }
285 +/
286         /**
287          * Output the written size when "File_Duplicate" option is used.
288          *
289          * Output the written size when "File_Duplicate" option is used.
290          *
291          * Params:
292          * value = The unique name of the duplicated stream (begin with "memory://")
293          * Returns:
294          * The size of the used buffer
295          */
296         size_t outputBufferGet(const(string) value)
297         {
298             return MediaInfoA_Output_Buffer_Get(handle, toStringz(value));
299         }
300         /**
301          * Output the written size when "File_Duplicate" option is used.
302          *
303          * Output the written size when "File_Duplicate" option is used.
304          *
305          * Params:
306          * pos = The position ?
307          * Returns:
308          * The size of the used buffer
309          */
310         size_t outputBufferGet(size_t pos)
311         {
312             return MediaInfoA_Output_Buffer_GetI(handle, pos);
313         }
314         /**
315          * Configure or get information about MediaInfoLib
316          *
317          * Params:
318          * option = The name of option
319          * value = The value of option
320          * Returns:
321          * Depend of the option: by default "" (nothing) means No, other means Yes
322          */
323         string option(const(string) option, const(string) value = "")
324         {
325             return to!string(MediaInfoA_Option(handle, toStringz(option), toStringz(value)));
326         }
327 
328         /*
329         static string optionStatic(const(string) option, const(string) value = "")
330         {
331             return to!string(MediaInfoA_Option_Static(handle, toStringz(option), toStringz(value)));
332         }*/
333         /**
334          * (NOT IMPLEMENTED YET) Get the state of the library
335          *
336          * Return values:
337          * <1000    No information is available for the file yet
338          * >=1000_<5000     Only local (into the file) information is available, getting Internet information (titles only) is no finished yet
339          * 5000     (only if Internet connection is accepted) User interaction is needed (use Option() with "Internet_Title_Get")
340          * Warning: even there is only one possible, user interaction (or the software) is needed
341          * >5000<=10000     Only local (into the file) information is available, getting Internet information (all) is no finished yet
342          * <10000   Done
343          */
344         size_t getState()
345         {
346             return MediaInfoA_State_Get(handle);
347         }
348         /**
349          * Count of streams of a stream kind (StreamNumber not filled), or count of piece of information in this stream.
350          *
351          * Params:
352          * streamKind = Kind of stream (general, video, audio...)
353          * streamNumber = Stream number in this kind of stream (first, second...)
354          */
355         size_t getCount(MediaInfo_stream_t streamKind, size_t streamNumber = -1)
356         {
357             return MediaInfoA_Count_Get(handle, streamKind, streamNumber);
358         }
359 }