libmediainfo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }