libmediainfo 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ # libmediainfo
2
+
3
+ Ruby bindings for [mediainfo][] that direct use `libmediainfo.so`
4
+ instead of parsing the command-line utility.
5
+
6
+ [mediainfo]: http://mediainfo.sourceforge.net
7
+
8
+ * [Homepage](https://github.com/pdkl95/ruby-libmediainfo#readme)
9
+ * [Issues](https://github.com/pdkl95/ruby-libmediainfo/issues)
10
+ * [Documentation](http://rubydoc.info/gems/libmediainfo/frames)
11
+ * [Email](mailto:pdkl95@thoughtnoise.net)
12
+
13
+
14
+ # Requirements
15
+
16
+ * [libmediainfo.so][] itself and any of its requirements (`libzen`)
17
+ * `MediaInfoDLL.h` which should come with the library, but may
18
+ require installing an additional "`-dev`" package if you use the
19
+ pre-compiled package available for some distros.
20
+
21
+ [libmediainfo]: http://mediainfo.sourceforge.net/en/Download
22
+
23
+ # Installation
24
+
25
+ ```bash
26
+ gem install libmediainfo
27
+ ```
28
+
29
+ # Usage
30
+
31
+ See the [examples][] directory. I'll write some proper documentation
32
+ some day.
33
+
34
+ # Copyright
35
+
36
+ Copyright 2013 Brent Sanders
37
+
38
+ See LICENSE.txt for details.
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+ require 'rake/extensiontask'
23
+
24
+ spec = Gem::Specification.load('libmediainfo.gemspec')
25
+
26
+ Rake::ExtensionTask.new do |ext|
27
+ ext.name = 'mediainfo'
28
+ ext.ext_dir = 'ext/mediainfo'
29
+ ext.lib_dir = 'lib/mediainfo'
30
+ ext.tmp_dir = 'tmp'
31
+ ext.source_pattern = '*.{c,h}'
32
+ ext.gem_spec = spec
33
+ end
34
+
35
+ require 'rubygems/tasks'
36
+ Gem::Tasks.new checksum: true, pgp: true
37
+
38
+
39
+ require 'rspec/core/rake_task'
40
+ RSpec::Core::RakeTask.new
41
+
42
+ task :test => :spec
43
+ task :default => :spec
44
+
45
+
46
+ require 'yard'
47
+ YARD::Rake::YardocTask.new
48
+ task :doc => :yard
49
+
50
+
51
+
@@ -0,0 +1,28 @@
1
+ #!/bin/env ruby
2
+ #
3
+ # This demo simply iterats through each field in
4
+ # each track that libmediainfo provided.
5
+
6
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
7
+ require 'mediainfo'
8
+
9
+ def show(path)
10
+ puts ">>> \"#{path}\""
11
+ info = MediaInfo.new(path)
12
+
13
+ info.each_track do |track|
14
+ track.each_field do|k,v|
15
+ puts "#{track.stream_type.name}[#{track.id}] #{k}: #{v.inspect}"
16
+ end
17
+ end
18
+ end
19
+
20
+ if ARGV.length < 1
21
+ puts "usage: #{File.basename($0)} <media_file> [<media_file> [...]]"
22
+ exit 1
23
+ end
24
+
25
+ ARGV.each do |media_file|
26
+ show media_file
27
+ end
28
+
@@ -0,0 +1,49 @@
1
+ #!/bin/env ruby
2
+ #
3
+ # An example that demonstrates how to request
4
+ # specific data fields about individual tracks.
5
+
6
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
7
+ require 'mediainfo'
8
+
9
+ def show(path)
10
+ puts "*** MediaInfo.new(\"#{path}\") ***"
11
+ info = MediaInfo.new(path)
12
+ puts info
13
+
14
+ g = info.general[0]
15
+ puts "Format: #{g['Format']} - #{g['Format/Info']}"
16
+ puts "Duration: #{g['Duration/String']}"
17
+
18
+ info.video.each do |track|
19
+ puts
20
+ puts "#{track}"
21
+ puts "VIDEO[#{track.id}] Codec: #{track['Codec']} - #{track['Codec/Info']}"
22
+ puts "VIDEO[#{track.id}] Resolution: #{track['Width']}x#{track['Height']}"
23
+ puts "VIDEO[#{track.id}] FrameRate: #{track['FrameRate/String']}"
24
+ puts "VIDEO[#{track.id}] Bits/Pixel: #{track['Bits-(Pixel*Frame)']}"
25
+ puts "VIDEO[#{track.id}] BitRate: #{track['BitRate/String']}"
26
+ end
27
+
28
+ info.audio.each do |track|
29
+ puts
30
+ puts "#{track}"
31
+ puts "AUDIO[#{track.id}] Codec: #{track['Codec']} - #{track['Codec/Info']}"
32
+ puts "AUDIO[#{track.id}] Channels: #{track['Channel(s)']}"
33
+ puts "AUDIO[#{track.id}] BitDepth: #{track['BitDepth/String']}"
34
+ puts "AUDIO[#{track.id}] Channels: #{track['SamplingRate']} (#{track['SamplingRate/String']})"
35
+ end
36
+ end
37
+
38
+ if ARGV.length < 1
39
+ puts "usage: #{File.basename($0)} <media_file> [<media_file> [...]]"
40
+ exit 1
41
+ end
42
+
43
+ ARGV.each do |media_file|
44
+ show media_file
45
+ end
46
+
47
+ #puts "***********"
48
+ #puts x.print_report!
49
+ #puts "***********"
@@ -0,0 +1,39 @@
1
+ #include "common.h"
2
+ #include "api.h"
3
+
4
+ mediainfo_api_t cMediaInfoAPI;
5
+
6
+ static void
7
+ check_binding(void *func, char *name)
8
+ {
9
+ if (!func) {
10
+ rb_raise(rb_eLoadError,
11
+ "Failed to bind MediaInfo_%s() from libmediainfo.so",
12
+ name);
13
+ }
14
+ }
15
+
16
+ void
17
+ Init_mediainfo_api(void)
18
+ {
19
+ MediaInfoDLL_Load();
20
+ if (!MediaInfoDLL_IsLoaded()) {
21
+ rb_raise(rb_eLoadError, "Mediainfo.so not loaded!\n");
22
+ }
23
+
24
+ #define MI_API(field, name) \
25
+ cMediaInfoAPI.field = JOIN(MediaInfo_,name); \
26
+ check_binding(cMediaInfoAPI.field, Q(name));
27
+
28
+ MI_API(new,New);
29
+ MI_API(delete,Delete);
30
+ MI_API(open,Open);
31
+ MI_API(close,Close);
32
+ MI_API(inform,Inform);
33
+ MI_API(geti,GetI);
34
+ MI_API(get,Get);
35
+ MI_API(option,Option);
36
+ MI_API(state_get,State_Get);
37
+ MI_API(count_get,Count_Get);
38
+ #undef MI_API
39
+ }
@@ -0,0 +1,21 @@
1
+ #ifndef GEM_MEDIAINFO_API_H
2
+ #define GEM_MEDIAINFO_API_H
3
+
4
+ struct mediainfo_api {
5
+ void * (*new)();
6
+ void (*delete)(void *);
7
+ size_t (*open)(void *, const MediaInfo_Char *);
8
+ void (*close)(void *);
9
+ const MediaInfo_Char * (*inform)(void *, size_t);
10
+ const MediaInfo_Char * (*geti)(void *, MediaInfo_stream_C, size_t, size_t, MediaInfo_info_C);
11
+ const MediaInfo_Char * (*get)(void *, MediaInfo_stream_C, size_t, const MediaInfo_Char *, MediaInfo_info_C, MediaInfo_info_C);
12
+ const MediaInfo_Char * (*option)(void *, const MediaInfo_Char *, const MediaInfo_Char *);
13
+ size_t (*state_get)(void *);
14
+ size_t (*count_get)(void *, MediaInfo_stream_C, size_t);
15
+ };
16
+ typedef struct mediainfo_api mediainfo_api_t;
17
+
18
+ extern mediainfo_api_t cMediaInfoAPI;
19
+
20
+
21
+ #endif /*GEM_MEDIAINFO_API_H*/
@@ -0,0 +1,19 @@
1
+ #ifndef LIBMI_MEDIAINFO_H
2
+ #define LIBMI_MEDIAINFO_H
3
+
4
+ #include <ruby.h>
5
+ #include <MediaInfoDLL/MediaInfoDLL.h>
6
+
7
+ #define Q(x) #x
8
+ #define JOIN_(a,b) a##b
9
+ #define JOIN(a,b) JOIN_(a,b)
10
+
11
+ #define GET_CLASS_STRUCT(type_t, mi, selfptr) \
12
+ type_t *mi; \
13
+ Data_Get_Struct(selfptr, type_t, mi);
14
+
15
+ #define MARK(x) \
16
+ if (x != Qnil) { rb_gc_mark(x); }
17
+
18
+
19
+ #endif /*GEM_MEDIAINFO_MEDIAINFO_H*/
@@ -0,0 +1,61 @@
1
+ #include "common.h"
2
+ #include "constants.h"
3
+ #include "mediainfo.h"
4
+
5
+ VALUE cMediaInfo_mStream;
6
+ VALUE cMediaInfo_mInfo;
7
+ VALUE cMediaInfo_mInfoOption;
8
+ VALUE cMediaInfo_mFileOption;
9
+
10
+ void
11
+ Init_mediainfo_constants(void)
12
+ {
13
+ #define MOD(name) \
14
+ JOIN(cMediaInfo_m,name) = rb_define_module_under(cMediaInfo, Q(name))
15
+
16
+ MOD(Stream);
17
+ MOD(Info);
18
+ MOD(InfoOption);
19
+ MOD(FileOption);
20
+ #undef MOD
21
+
22
+ #define MI_CONST(cat, name) \
23
+ JOIN(JOIN(MediaInfo_,cat),JOIN(_,name))
24
+
25
+ #define C(cat, name) \
26
+ rb_define_const( JOIN(cMediaInfo_m,cat), \
27
+ Q(name), \
28
+ INT2NUM(MI_CONST(cat,name)))
29
+
30
+ C(Stream,General);
31
+ C(Stream,Video);
32
+ C(Stream,Audio);
33
+ C(Stream,Text);
34
+ C(Stream,Chapters);
35
+ C(Stream,Image);
36
+ C(Stream,Menu);
37
+ C(Stream,Max);
38
+
39
+ C(Info,Name);
40
+ C(Info,Text);
41
+ C(Info,Measure);
42
+ C(Info,Options);
43
+ C(Info,Name_Text);
44
+ C(Info,Measure_Text);
45
+ C(Info,Info);
46
+ C(Info,HowTo);
47
+ C(Info,Max);
48
+
49
+ C(InfoOption,ShowInInform);
50
+ C(InfoOption,Reserved);
51
+ C(InfoOption,ShowInSupported);
52
+ C(InfoOption,TypeOfValue);
53
+ C(InfoOption,Max);
54
+
55
+ C(FileOption,Nothing);
56
+ C(FileOption,NoRecursive);
57
+ C(FileOption,CloseAll);
58
+ C(FileOption,Max);
59
+ #undef C
60
+ #undef MI_CONST_NAME
61
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef GEM_MEDIAINFO_CONSTANTS_H
2
+ #define GEM_MEDIAINFO_CONSTANTS_H
3
+
4
+ extern VALUE cMediaInfo_mStream;
5
+ extern VALUE cMediaInfo_mInfo;
6
+ extern VALUE cMediaInfo_mInfoOption;
7
+ extern VALUE cMediaInfo_mFileOption;
8
+
9
+ void Init_mediainfo_constants(void);
10
+
11
+ #endif /*GEM_MEDIAINFO_CONSTANTS_H*/
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mkmf'
4
+
5
+ [ 'stdlib.h', 'string.h', 'wchar.h'
6
+ ].each do |hdr|
7
+ find_header(hdr) or fail "missing required header: #{hdr}"
8
+ end
9
+
10
+ pkg_config 'libmediainfo' or fail "pkg_config failed for libmediainfo"
11
+
12
+ mi_hdr = 'MediaInfoDLL/MediaInfoDLL.h'
13
+ have_header(mi_hdr) or fail "missing libmediainfo header \"#{mi_hdr}\""
14
+
15
+ #create_header
16
+ create_makefile 'mediainfo'
17
+
18
+ if ENV['V'] == '1'
19
+ system("sed -i -e 's/^V = 0/V = 1/' Makefile")
20
+ end
@@ -0,0 +1,17 @@
1
+ #include "common.h"
2
+ #include "libmediainfo.h"
3
+ #include "api.h"
4
+ #include "constants.h"
5
+ #include "mediainfo.h"
6
+ #include "stream_type.h"
7
+ #include "track.h"
8
+
9
+ void
10
+ Init_mediainfo(void)
11
+ {
12
+ Init_mediainfo_api();
13
+ Init_mediainfo_MediaInfo();
14
+ Init_mediainfo_MediaInfo_StreamType();
15
+ Init_mediainfo_MediaInfo_Track();
16
+ Init_mediainfo_constants();
17
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef GEM_MEDIAINFO_LIBMEDIAINFO_H
2
+ #define GEM_MEDIAINFO_LIBMEDIAINFO_H
3
+
4
+ void Init_mediainfo(void);
5
+
6
+ #endif /*GEM_MEDIAINFO_LIBMEDIAINFO_H*/
@@ -0,0 +1,384 @@
1
+ #include "common.h"
2
+ #include "mediainfo.h"
3
+ #include "unicode.h"
4
+ #include "api.h"
5
+ #include "constants.h"
6
+ #include "stream_type.h"
7
+
8
+ VALUE cMediaInfo;
9
+
10
+ /***************************************************************************
11
+ * struct mediainfo
12
+ */
13
+
14
+ static mediainfo_t *
15
+ mediainfo_alloc()
16
+ {
17
+ mediainfo_t *mi;
18
+ mi = ALLOC(mediainfo_t);
19
+ mi->handle = cMediaInfoAPI.new();
20
+
21
+ mi->path = Qnil;
22
+ mi->stream_types = Qnil;
23
+ mi->tracks = Qnil;
24
+ mi->general = Qnil;
25
+ mi->video = Qnil;
26
+ mi->audio = Qnil;
27
+ mi->text = Qnil;
28
+ mi->chapters = Qnil;
29
+ mi->image = Qnil;
30
+ mi->menu = Qnil;
31
+
32
+ return mi;
33
+ }
34
+
35
+ static void
36
+ mediainfo_free(mediainfo_t *mi)
37
+ {
38
+ cMediaInfoAPI.delete(mi->handle);
39
+ xfree(mi);
40
+ }
41
+
42
+ static void
43
+ mediainfo_mark(mediainfo_t *mi)
44
+ {
45
+ MARK(mi->path);
46
+ MARK(mi->stream_types);
47
+ MARK(mi->tracks);
48
+ MARK(mi->general);
49
+ MARK(mi->video);
50
+ MARK(mi->audio);
51
+ MARK(mi->text);
52
+ MARK(mi->chapters);
53
+ MARK(mi->image);
54
+ MARK(mi->menu);
55
+ }
56
+
57
+ static VALUE
58
+ mediainfo_allocate(VALUE klass) {
59
+ mediainfo_t *mi = mediainfo_alloc();
60
+ if (!mi->handle) {
61
+ rb_raise(rb_eRuntimeError, "MediaInfo_New() failed!");
62
+ }
63
+
64
+ mi->stream_types = rb_ary_new();
65
+ mi->tracks = rb_ary_new();
66
+
67
+ return Data_Wrap_Struct(klass,
68
+ mediainfo_mark,
69
+ mediainfo_free,
70
+ mi);
71
+ }
72
+
73
+ #define GETTER(name) \
74
+ static VALUE \
75
+ JOIN(mediainfo_get_,name)(VALUE self) \
76
+ { \
77
+ UNPACK_MI; \
78
+ return mi->name; \
79
+ }
80
+ GETTER(path);
81
+ GETTER(stream_types);
82
+ GETTER(tracks);
83
+ GETTER(general);
84
+ GETTER(video);
85
+ GETTER(audio);
86
+ GETTER(text);
87
+ GETTER(chapters);
88
+ GETTER(image);
89
+ GETTER(menu);
90
+ #undef GETTER
91
+
92
+ static VALUE
93
+ mediainfo_compare(VALUE self, VALUE other)
94
+ {
95
+ GET_MEDIAINFO(a, self);
96
+ GET_MEDIAINFO(b, other);
97
+ return rb_funcall(a->path, rb_intern("<=>"), 1, b->path);
98
+ }
99
+
100
+ static VALUE
101
+ mediainfo_inspect(VALUE self)
102
+ {
103
+ char *buf;
104
+ UNPACK_MI;
105
+
106
+ if (mi->path == Qnil) {
107
+ return rb_str_new2("#<MediaInfo nil>");
108
+ } else {
109
+ #define INSPECT_FMT "#<MediaInfo \"%s\">"
110
+ buf = alloca(RSTRING_LEN(mi->path) + sizeof(INSPECT_FMT));
111
+ sprintf(buf, INSPECT_FMT, RSTRING_PTR(mi->path));
112
+ #undef INSPECT_FMT
113
+ return rb_str_new2(buf);
114
+ }
115
+ }
116
+
117
+ static VALUE
118
+ mediainfo_to_s(VALUE self)
119
+ {
120
+ return mediainfo_inspect(self);
121
+ }
122
+
123
+ static VALUE
124
+ mediainfo_load_track_info(VALUE self)
125
+ {
126
+ VALUE st;
127
+ VALUE argv[2];
128
+ VALUE types[MediaInfo_Stream_Max];
129
+ int stream_type;
130
+ UNPACK_MI;
131
+
132
+ argv[0] = self;
133
+
134
+ for (stream_type = 0; stream_type < MediaInfo_Stream_Max; stream_type++) {
135
+ argv[1] = INT2NUM(stream_type);
136
+ st = rb_class_new_instance(2, argv, cMediaInfo_cStreamType);
137
+ rb_ary_push(mi->stream_types, st);
138
+ types[stream_type] = st;
139
+ }
140
+
141
+ mi->general = types[MediaInfo_Stream_General];
142
+ mi->video = types[MediaInfo_Stream_Video];
143
+ mi->audio = types[MediaInfo_Stream_Audio];
144
+ mi->text = types[MediaInfo_Stream_Text];
145
+ mi->chapters = types[MediaInfo_Stream_Chapters];
146
+ mi->image = types[MediaInfo_Stream_Image];
147
+ mi->menu = types[MediaInfo_Stream_Menu];
148
+
149
+ return self;
150
+ }
151
+
152
+ static VALUE
153
+ mediainfo_open(int argc, VALUE *argv, VALUE self)
154
+ {
155
+ MediaInfo_Char *path;
156
+ size_t retval;
157
+ UNPACK_MI;
158
+
159
+ rb_scan_args(argc, argv, "10", &mi->path);
160
+ mi->path = StringValue(mi->path);
161
+ path = rstring_to_mediainfo_chars(mi->path);
162
+
163
+ if (!cMediaInfoAPI.open(mi->handle, path)) {
164
+ rb_raise(rb_eIOError, "MediaInfo_Open() failed");
165
+ }
166
+ RSTRING_TO_MINFO_FREE(path);
167
+
168
+ return mediainfo_load_track_info(self);
169
+ }
170
+
171
+ static VALUE
172
+ mediainfo_initialize(int argc, VALUE *argv, VALUE self)
173
+ {
174
+ if (argc > 0 ) {
175
+ return mediainfo_open(argc, argv, self);
176
+ } else {
177
+ return self;
178
+ }
179
+ }
180
+
181
+ static VALUE
182
+ mediainfo_close(VALUE self)
183
+ {
184
+ UNPACK_MI;
185
+ cMediaInfoAPI.close(mi->handle);
186
+ return self;
187
+ }
188
+
189
+ static const MediaInfo_Char *
190
+ mediainfo_report_string(mediainfo_t *mi)
191
+ {
192
+ const MediaInfo_Char *str = cMediaInfoAPI.inform(mi->handle, 0);
193
+ return str;
194
+ }
195
+
196
+ static VALUE
197
+ mediainfo_inform(VALUE self)
198
+ {
199
+ VALUE rstr;
200
+ const MediaInfo_Char *str;
201
+ UNPACK_MI;
202
+
203
+ str = mediainfo_report_string(mi);
204
+ rstr = mediainfo_chars_to_rstring(str);
205
+ return rstr;
206
+ }
207
+
208
+ VALUE
209
+ mediainfo_get_i(VALUE self, VALUE stream_type, VALUE stream_id, VALUE field_id, VALUE request_type)
210
+ {
211
+ const MediaInfo_Char *mi_str;
212
+ UNPACK_MI;
213
+
214
+ mi_str = cMediaInfoAPI.geti(mi->handle,
215
+ NUM2INT(stream_type),
216
+ NUM2INT(stream_id),
217
+ NUM2INT(field_id),
218
+ NUM2INT(request_type));
219
+
220
+ return mediainfo_string_to_rb(mi_str);
221
+ }
222
+
223
+ static VALUE
224
+ mediainfo_get(VALUE self, VALUE stream_type, VALUE stream_id, VALUE field_name, VALUE request_type)
225
+ {
226
+ MediaInfo_Char *mi_field_name;
227
+ const MediaInfo_Char *mi_str;
228
+ UNPACK_MI;
229
+
230
+ mi_field_name = rstring_to_mediainfo_chars(field_name);
231
+
232
+ mi_str = cMediaInfoAPI.get(mi->handle,
233
+ NUM2INT(stream_type),
234
+ NUM2INT(stream_id),
235
+ mi_field_name,
236
+ NUM2INT(request_type),
237
+ 0);
238
+
239
+ RSTRING_TO_MINFO_FREE(mi_field_name);
240
+
241
+ return mediainfo_string_to_rb(mi_str);
242
+ }
243
+
244
+ static VALUE
245
+ mediainfo_option(VALUE self, VALUE name, VALUE value)
246
+ {
247
+ VALUE rstr;
248
+ MediaInfo_Char *mi_name;
249
+ MediaInfo_Char *mi_value;
250
+ const MediaInfo_Char *mi_str;
251
+ UNPACK_MI;
252
+
253
+ mi_name = rstring_to_mediainfo_chars(name);
254
+ mi_value = rstring_to_mediainfo_chars(value);
255
+
256
+ mi_str = cMediaInfoAPI.option(mi->handle, mi_name, mi_value);
257
+
258
+ RSTRING_TO_MINFO_FREE(mi_value);
259
+ RSTRING_TO_MINFO_FREE(mi_name);
260
+
261
+ rstr = mediainfo_chars_to_rstring(mi_str);
262
+ return rstr;
263
+ }
264
+
265
+ static VALUE
266
+ mediainfo_state_get(VALUE self)
267
+ {
268
+ UNPACK_MI;
269
+ return INT2NUM(cMediaInfoAPI.state_get(mi->handle));
270
+ }
271
+
272
+ VALUE
273
+ mediainfo_count_get(VALUE self, VALUE stream_type, VALUE stream_id)
274
+ {
275
+ UNPACK_MI;
276
+ return INT2NUM(cMediaInfoAPI.count_get(mi->handle,
277
+ NUM2INT(stream_type),
278
+ NUM2INT(stream_id)));
279
+ }
280
+
281
+ static VALUE
282
+ mediainfo_stream_type(int argc, VALUE *argv, VALUE self)
283
+ {
284
+ VALUE type_number;
285
+ rb_scan_args(argc, argv, "10", &type_number);
286
+ return rb_intern( mediainfo_stream_type_to_name(NUM2INT(type_number)) );
287
+ }
288
+
289
+
290
+ static VALUE
291
+ mediainfo_num_streams(VALUE self, VALUE type)
292
+ {
293
+ return mediainfo_count_get(self, type, INT2NUM(-1));
294
+ }
295
+
296
+ static VALUE
297
+ mediainfo_num_fields(VALUE self, VALUE type, VALUE stream_id)
298
+ {
299
+ return mediainfo_count_get(self, type, stream_id);
300
+ }
301
+
302
+ static VALUE
303
+ mediainfo_get_field(VALUE self, VALUE stream_type, VALUE stream_id, VALUE field_name)
304
+ {
305
+ return mediainfo_get(self, stream_type, stream_id, field_name,
306
+ INT2NUM(MediaInfo_Info_Text));
307
+ }
308
+
309
+ #define FIELD_GET(t,T) \
310
+ static VALUE \
311
+ JOIN(mediainfo_f_,t)(VALUE self, VALUE stream_id, VALUE field_name) \
312
+ { \
313
+ return mediainfo_get_field(self, INT2NUM(JOIN(MediaInfo_Stream_,T)), \
314
+ stream_id, field_name); \
315
+ }
316
+ FIELD_GET(general,General);
317
+ FIELD_GET(video,Video);
318
+ FIELD_GET(audio,Audio);
319
+ FIELD_GET(text,Text);
320
+ FIELD_GET(chapters,Chapters);
321
+ FIELD_GET(image,Image);
322
+ FIELD_GET(menu,Menu);
323
+ #undef FIELD_GET
324
+
325
+ static VALUE
326
+ mediainfo_each(VALUE self)
327
+ {
328
+ UNPACK_MI;
329
+ return rb_ary_each(mi->tracks);
330
+ }
331
+
332
+ void
333
+ Init_mediainfo_MediaInfo(void)
334
+ {
335
+ cMediaInfo = rb_define_class("MediaInfo", rb_cObject);
336
+ rb_define_alloc_func(cMediaInfo, mediainfo_allocate);
337
+
338
+ rb_define_method(cMediaInfo, "<=>", mediainfo_compare, 1);
339
+ rb_define_method(cMediaInfo, "each_track", mediainfo_each, 0);
340
+
341
+ #define GET(name) \
342
+ rb_define_method(cMediaInfo, \
343
+ Q(name), \
344
+ JOIN(mediainfo_get_,name), \
345
+ 0);
346
+ GET(path);
347
+ GET(stream_types);
348
+ GET(tracks);
349
+ GET(general);
350
+ GET(video);
351
+ GET(audio);
352
+ GET(text);
353
+ GET(chapters);
354
+ GET(image);
355
+ GET(menu);
356
+ #undef GET
357
+
358
+ #define M(name, numargs) \
359
+ rb_define_method(cMediaInfo, Q(name), JOIN(mediainfo_,name), numargs);
360
+ M(initialize, -1);
361
+ M(inspect, 0);
362
+ M(to_s, 0);
363
+ M(open, -1);
364
+ M(close, 0);
365
+ M(inform, 0);
366
+ M(get_i, 4);
367
+ M(get, 4);
368
+ M(option, 2);
369
+ M(state_get, 0);
370
+ M(count_get, 2);
371
+ M(stream_type, -1);
372
+ M(num_streams, 1);
373
+ M(num_fields, 2);
374
+ M(get_field, 3);
375
+ M(f_general, 2);
376
+ M(f_video, 2);
377
+ M(f_audio, 2);
378
+ M(f_text, 2);
379
+ M(f_chapters, 2);
380
+ M(f_image, 2);
381
+ M(f_menu, 2);
382
+ M(each, 0);
383
+ #undef M
384
+ }