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.
- data/.document +3 -0
- data/.gitignore +27 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +8 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +675 -0
- data/README.md +38 -0
- data/Rakefile +51 -0
- data/example/dump_everything.rb +28 -0
- data/example/specific_fields.rb +49 -0
- data/ext/mediainfo/api.c +39 -0
- data/ext/mediainfo/api.h +21 -0
- data/ext/mediainfo/common.h +19 -0
- data/ext/mediainfo/constants.c +61 -0
- data/ext/mediainfo/constants.h +11 -0
- data/ext/mediainfo/extconf.rb +20 -0
- data/ext/mediainfo/libmediainfo.c +17 -0
- data/ext/mediainfo/libmediainfo.h +6 -0
- data/ext/mediainfo/mediainfo.c +384 -0
- data/ext/mediainfo/mediainfo.h +33 -0
- data/ext/mediainfo/stream_type.c +171 -0
- data/ext/mediainfo/stream_type.h +26 -0
- data/ext/mediainfo/track.c +205 -0
- data/ext/mediainfo/track.h +24 -0
- data/ext/mediainfo/unicode.c +76 -0
- data/ext/mediainfo/unicode.h +24 -0
- data/lib/mediainfo.rb +1 -0
- data/lib/mediainfo/version.rb +71 -0
- data/libmediainfo.gemspec +30 -0
- data/spec/libmediainfo_spec.rb +30 -0
- data/spec/spec_helper.rb +5 -0
- metadata +195 -0
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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 "***********"
|
data/ext/mediainfo/api.c
ADDED
@@ -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
|
+
}
|
data/ext/mediainfo/api.h
ADDED
@@ -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,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
|
+
}
|