ffruby 0.0.1
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/README +1 -0
- data/Rakefile +147 -0
- data/ext/ffruby/extconf.rb +13 -0
- data/ext/ffruby/ffruby.c +35 -0
- data/ext/ffruby/ffrubyfile.c +239 -0
- data/ext/ffruby/ffrubystream.c +196 -0
- data/lib/ffruby/version.rb +9 -0
- metadata +65 -0
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
README
|
data/Rakefile
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "rake/clean"
|
3
|
+
require "rake/gempackagetask"
|
4
|
+
require "rake/rdoctask"
|
5
|
+
require "rake/testtask"
|
6
|
+
require "fileutils"
|
7
|
+
require "yaml"
|
8
|
+
include FileUtils
|
9
|
+
require "lib/ffruby/version"
|
10
|
+
|
11
|
+
GEM_NAME = "ffruby"
|
12
|
+
REV = nil
|
13
|
+
|
14
|
+
GEM_VERSION = FFruby::VERSION::STRING + (REV ? ".#{REV}" : "")
|
15
|
+
CLEAN.include [
|
16
|
+
"ext/ffruby/*.{bundle,so,obj,pdb,lib,def,exp}",
|
17
|
+
"ext/ffruby/Makefile",
|
18
|
+
"**/.*.sw?",
|
19
|
+
"*.gem",
|
20
|
+
".config"
|
21
|
+
]
|
22
|
+
RDOC_OPTS = ["--quiet", "--title", "FFruby Reference", "--main", "README", "--inline-source"]
|
23
|
+
|
24
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
25
|
+
@config = nil
|
26
|
+
def rubyforge_username
|
27
|
+
unless @config
|
28
|
+
begin
|
29
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
30
|
+
rescue
|
31
|
+
puts <<-EOS
|
32
|
+
ERROR: No rubyforge config file found: #{@config_file}"
|
33
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
34
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
35
|
+
EOS
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@rubyforge_username ||= @config["username"]
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Does a full compile, test run"
|
43
|
+
task :default => [:compile, :test]
|
44
|
+
|
45
|
+
desc "Compiles all extensions"
|
46
|
+
task :compile => [:ffruby] do
|
47
|
+
if Dir.glob(File.join("lib","ffruby*.*")).length == 0
|
48
|
+
STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
49
|
+
STDERR.puts "Gem actually failed to build. Your system is"
|
50
|
+
STDERR.puts "NOT configured properly to build ffruby."
|
51
|
+
STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
52
|
+
exit(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Packages up FFruby."
|
57
|
+
task :package => [:clean]
|
58
|
+
|
59
|
+
desc "Releases packages for all FFruby packages and platforms."
|
60
|
+
task :release => [:package]
|
61
|
+
|
62
|
+
desc "Run all the tests"
|
63
|
+
Rake::TestTask.new do | test_task |
|
64
|
+
test_task.libs << "test"
|
65
|
+
test_task.test_files = FileList["test/test_*.rb"]
|
66
|
+
test_task.verbose = true
|
67
|
+
end
|
68
|
+
|
69
|
+
Rake::RDocTask.new do | rdoc |
|
70
|
+
rdoc.rdoc_dir = "doc/rdoc"
|
71
|
+
rdoc.options += RDOC_OPTS
|
72
|
+
rdoc.main = "README"
|
73
|
+
rdoc.rdoc_files.add ["README", "lib/**/*.rb"]
|
74
|
+
end
|
75
|
+
|
76
|
+
spec =
|
77
|
+
Gem::Specification.new do | specification |
|
78
|
+
specification.name = GEM_NAME
|
79
|
+
specification.version = GEM_VERSION
|
80
|
+
specification.platform = Gem::Platform::RUBY
|
81
|
+
specification.has_rdoc = true
|
82
|
+
specification.rdoc_options += RDOC_OPTS
|
83
|
+
specification.extra_rdoc_files = ["README"]
|
84
|
+
specification.summary = "a library that does something with media files!"
|
85
|
+
specification.description = specification.summary
|
86
|
+
specification.author = "ffruby: James Le Cuirot, gem: Wayne E. Seguin"
|
87
|
+
specification.email = "wayneeseguin at gmail dot com"
|
88
|
+
specification.homepage = "ffruby.rubyforge.org"
|
89
|
+
|
90
|
+
specification.files = %w(README Rakefile) +
|
91
|
+
Dir.glob("{bin,doc,test,lib,extras}/**/*") +
|
92
|
+
Dir.glob("ext/**/*.{h,c,rb,rl}") +
|
93
|
+
%w[ext/ffruby/ffruby.c] # needed because it's generated later
|
94
|
+
|
95
|
+
specification.require_path = "lib"
|
96
|
+
specification.extensions = FileList["ext/**/extconf.rb"].to_a
|
97
|
+
specification.bindir = "bin"
|
98
|
+
end
|
99
|
+
|
100
|
+
Rake::GemPackageTask.new(spec) do | package |
|
101
|
+
package.need_tar = true
|
102
|
+
package.gem_spec = spec
|
103
|
+
end
|
104
|
+
|
105
|
+
extension = "ffruby"
|
106
|
+
ext = "ext/ffruby"
|
107
|
+
ext_so = "#{ext}/#{extension}.#{Config::CONFIG["DLEXT"]}"
|
108
|
+
ext_files = FileList[
|
109
|
+
"#{ext}/*.c",
|
110
|
+
"#{ext}/*.h",
|
111
|
+
"#{ext}/*.rl",
|
112
|
+
"#{ext}/extconf.rb",
|
113
|
+
"#{ext}/Makefile",
|
114
|
+
"lib"
|
115
|
+
]
|
116
|
+
|
117
|
+
task "lib" do
|
118
|
+
directory "lib"
|
119
|
+
end
|
120
|
+
|
121
|
+
desc "Builds just the #{extension} extension"
|
122
|
+
task extension.to_sym => ["#{ext}/Makefile", ext_so ]
|
123
|
+
|
124
|
+
file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
|
125
|
+
#Dir.chdir(ext) do
|
126
|
+
if `uname.a`.match(/Darwin Kernel Version 9\.0\.0:.*i386/)
|
127
|
+
ENV["ARCHFLAGS"] = "-arch i386"
|
128
|
+
end
|
129
|
+
ruby "extconf.rb"
|
130
|
+
#end
|
131
|
+
end
|
132
|
+
|
133
|
+
file ext_so => ext_files do
|
134
|
+
Dir.chdir(ext) do
|
135
|
+
sh(PLATFORM =~ /win32/ ? "nmake" : "make")
|
136
|
+
end
|
137
|
+
cp ext_so, "lib"
|
138
|
+
end
|
139
|
+
|
140
|
+
task :install do
|
141
|
+
sh %{rake package}
|
142
|
+
sh %{sudo gem install pkg/#{GEM_NAME}-#{GEM_VERSION}}
|
143
|
+
end
|
144
|
+
|
145
|
+
task :uninstall => [:clean] do
|
146
|
+
sh %{sudo gem uninstall #{GEM_NAME}}
|
147
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
|
3
|
+
require "mkmf"
|
4
|
+
dir_config("ffmpeg")
|
5
|
+
have_library("avformat")
|
6
|
+
have_library("avcodec")
|
7
|
+
create_makefile("ffruby")
|
8
|
+
|
9
|
+
# avcodec is not built for ppc
|
10
|
+
if `uname -a`.match(/i386/)
|
11
|
+
`sed '1,$s/-arch ppc//' Makefile >> ./Makefile.tmp`
|
12
|
+
`mv ./Makefile.tmp Makefile`
|
13
|
+
end
|
data/ext/ffruby/ffruby.c
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2007 James Le Cuirot
|
3
|
+
*
|
4
|
+
* This file is part of FFruby.
|
5
|
+
*
|
6
|
+
* FFruby is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* FFruby is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with FFmpeg; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#define _GNU_SOURCE
|
22
|
+
#include <ruby.h>
|
23
|
+
#include <ffmpeg/avformat.h>
|
24
|
+
#include <ffmpeg/avcodec.h>
|
25
|
+
|
26
|
+
extern void Init_ffrf();
|
27
|
+
extern void Init_ffrs();
|
28
|
+
|
29
|
+
void Init_ffruby()
|
30
|
+
{
|
31
|
+
av_register_all();
|
32
|
+
|
33
|
+
Init_ffrf();
|
34
|
+
Init_ffrs();
|
35
|
+
}
|
@@ -0,0 +1,239 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2007 James Le Cuirot
|
3
|
+
*
|
4
|
+
* This file is part of FFruby.
|
5
|
+
*
|
6
|
+
* FFruby is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* FFruby is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with FFmpeg; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#define _GNU_SOURCE
|
22
|
+
#include <ruby.h>
|
23
|
+
#include <ffmpeg/avformat.h>
|
24
|
+
#include <ffmpeg/avcodec.h>
|
25
|
+
#include <stdio.h>
|
26
|
+
|
27
|
+
VALUE cFFrubyFile;
|
28
|
+
|
29
|
+
extern VALUE cFFrubyVideoStream;
|
30
|
+
extern VALUE cFFrubyAudioStream;
|
31
|
+
|
32
|
+
static void ffrf_free(AVFormatContext *fmt)
|
33
|
+
{
|
34
|
+
unsigned int i;
|
35
|
+
|
36
|
+
if (fmt != NULL)
|
37
|
+
{
|
38
|
+
for (i = 0; i < fmt->nb_streams; i++)
|
39
|
+
{
|
40
|
+
if (fmt->streams[i]->codec->codec != NULL)
|
41
|
+
avcodec_close(fmt->streams[i]->codec);
|
42
|
+
}
|
43
|
+
|
44
|
+
av_close_input_file(fmt);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
static AVFormatContext* ffrf_get_fmt(VALUE self)
|
49
|
+
{
|
50
|
+
AVFormatContext *fmt;
|
51
|
+
Data_Get_Struct(self, AVFormatContext, fmt);
|
52
|
+
return fmt;
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE ffrf_alloc(VALUE klass)
|
56
|
+
{
|
57
|
+
return Data_Wrap_Struct(klass, 0, ffrf_free, NULL);
|
58
|
+
}
|
59
|
+
|
60
|
+
static VALUE ffrf_title(VALUE self)
|
61
|
+
{
|
62
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
63
|
+
return rb_str_new2(fmt->title);
|
64
|
+
}
|
65
|
+
|
66
|
+
static VALUE ffrf_author(VALUE self)
|
67
|
+
{
|
68
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
69
|
+
return rb_str_new2(fmt->author);
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE ffrf_copyright(VALUE self)
|
73
|
+
{
|
74
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
75
|
+
return rb_str_new2(fmt->copyright);
|
76
|
+
}
|
77
|
+
|
78
|
+
static VALUE ffrf_comment(VALUE self)
|
79
|
+
{
|
80
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
81
|
+
return rb_str_new2(fmt->comment);
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE ffrf_album(VALUE self)
|
85
|
+
{
|
86
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
87
|
+
return rb_str_new2(fmt->album);
|
88
|
+
}
|
89
|
+
|
90
|
+
static VALUE ffrf_genre(VALUE self)
|
91
|
+
{
|
92
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
93
|
+
return rb_str_new2(fmt->genre);
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE ffrf_year(VALUE self)
|
97
|
+
{
|
98
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
99
|
+
return INT2NUM(fmt->year);
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE ffrf_track(VALUE self)
|
103
|
+
{
|
104
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
105
|
+
return INT2NUM(fmt->track);
|
106
|
+
}
|
107
|
+
|
108
|
+
static VALUE ffrf_duration(VALUE self)
|
109
|
+
{
|
110
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
111
|
+
return rb_float_new((double) fmt->duration / (double) AV_TIME_BASE);
|
112
|
+
}
|
113
|
+
|
114
|
+
static VALUE ffrf_bit_rate(VALUE self)
|
115
|
+
{
|
116
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
117
|
+
return INT2NUM(fmt->bit_rate);
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE ffrf_format(VALUE self)
|
121
|
+
{
|
122
|
+
AVFormatContext *fmt = ffrf_get_fmt(self);
|
123
|
+
return rb_str_new2(fmt->iformat->name);
|
124
|
+
}
|
125
|
+
|
126
|
+
static VALUE ffrf_streams(VALUE self)
|
127
|
+
{
|
128
|
+
unsigned int i;
|
129
|
+
AVFormatContext *fmt;
|
130
|
+
VALUE streams;
|
131
|
+
VALUE* args;
|
132
|
+
|
133
|
+
if ((streams = rb_iv_get(self, "@streams")) == Qnil)
|
134
|
+
{
|
135
|
+
fmt = ffrf_get_fmt(self);
|
136
|
+
streams = rb_ary_new();
|
137
|
+
rb_iv_set(self, "@streams", streams);
|
138
|
+
|
139
|
+
args = (VALUE*) ALLOCA_N(VALUE*, 2);
|
140
|
+
args[0] = self;
|
141
|
+
|
142
|
+
for (i = 0; i < fmt->nb_streams; i++)
|
143
|
+
{
|
144
|
+
args[1] = INT2FIX(i);
|
145
|
+
|
146
|
+
switch (fmt->streams[i]->codec->codec_type)
|
147
|
+
{
|
148
|
+
case CODEC_TYPE_VIDEO:
|
149
|
+
rb_ary_push(streams, rb_class_new_instance(2, args, cFFrubyVideoStream));
|
150
|
+
break;
|
151
|
+
case CODEC_TYPE_AUDIO:
|
152
|
+
rb_ary_push(streams, rb_class_new_instance(2, args, cFFrubyAudioStream));
|
153
|
+
break;
|
154
|
+
default:
|
155
|
+
break;
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
return streams;
|
161
|
+
}
|
162
|
+
|
163
|
+
static VALUE ffrf_av_streams(VALUE self, VALUE klass)
|
164
|
+
{
|
165
|
+
VALUE stream;
|
166
|
+
VALUE streams;
|
167
|
+
VALUE typed_streams;
|
168
|
+
unsigned int i;
|
169
|
+
|
170
|
+
streams = rb_funcall(self, rb_intern("streams"), 0);
|
171
|
+
typed_streams = rb_ary_new();
|
172
|
+
Check_Type(streams, T_ARRAY);
|
173
|
+
|
174
|
+
for (i = 0; i < RARRAY(streams)->len; i++)
|
175
|
+
{
|
176
|
+
if (rb_obj_is_kind_of((stream = rb_ary_entry(streams, i)), klass))
|
177
|
+
rb_ary_push(typed_streams, stream);
|
178
|
+
}
|
179
|
+
|
180
|
+
return typed_streams;
|
181
|
+
}
|
182
|
+
|
183
|
+
static VALUE ffrf_video_streams(VALUE self)
|
184
|
+
{
|
185
|
+
return ffrf_av_streams(self, cFFrubyVideoStream);
|
186
|
+
}
|
187
|
+
|
188
|
+
static VALUE ffrf_audio_streams(VALUE self)
|
189
|
+
{
|
190
|
+
return ffrf_av_streams(self, cFFrubyAudioStream);
|
191
|
+
}
|
192
|
+
|
193
|
+
static VALUE ffrf_initialize(VALUE self, VALUE filename)
|
194
|
+
{
|
195
|
+
char* msg;
|
196
|
+
AVFormatContext *fmt;
|
197
|
+
VALUE exception;
|
198
|
+
VALUE filename_str = rb_funcall(filename, rb_intern("to_s"), 0);
|
199
|
+
|
200
|
+
if (av_open_input_file(&fmt, RSTRING(filename_str)->ptr, NULL, 0, NULL) != 0)
|
201
|
+
{
|
202
|
+
asprintf(&msg, "Cannot open file %s!", RSTRING(filename_str)->ptr);
|
203
|
+
exception = rb_exc_new2(rb_eIOError, msg);
|
204
|
+
free(msg);
|
205
|
+
rb_exc_raise(exception);
|
206
|
+
}
|
207
|
+
|
208
|
+
if (av_find_stream_info(fmt) < 0)
|
209
|
+
{
|
210
|
+
asprintf(&msg, "Problem reading file %s!", RSTRING(filename_str)->ptr);
|
211
|
+
exception = rb_exc_new2(rb_eIOError, msg);
|
212
|
+
free(msg);
|
213
|
+
rb_exc_raise(exception);
|
214
|
+
}
|
215
|
+
|
216
|
+
DATA_PTR(self) = fmt;
|
217
|
+
return self;
|
218
|
+
}
|
219
|
+
|
220
|
+
void Init_ffrf()
|
221
|
+
{
|
222
|
+
cFFrubyFile = rb_define_class("FFrubyFile", rb_cObject);
|
223
|
+
rb_define_alloc_func(cFFrubyFile, ffrf_alloc);
|
224
|
+
rb_define_method(cFFrubyFile, "initialize", ffrf_initialize, 1);
|
225
|
+
rb_define_method(cFFrubyFile, "title", ffrf_title, 0);
|
226
|
+
rb_define_method(cFFrubyFile, "author", ffrf_author, 0);
|
227
|
+
rb_define_method(cFFrubyFile, "copyright", ffrf_copyright, 0);
|
228
|
+
rb_define_method(cFFrubyFile, "comment", ffrf_comment, 0);
|
229
|
+
rb_define_method(cFFrubyFile, "album", ffrf_album, 0);
|
230
|
+
rb_define_method(cFFrubyFile, "genre", ffrf_genre, 0);
|
231
|
+
rb_define_method(cFFrubyFile, "year", ffrf_year, 0);
|
232
|
+
rb_define_method(cFFrubyFile, "track", ffrf_track, 0);
|
233
|
+
rb_define_method(cFFrubyFile, "duration", ffrf_duration, 0);
|
234
|
+
rb_define_method(cFFrubyFile, "bit_rate", ffrf_bit_rate, 0);
|
235
|
+
rb_define_method(cFFrubyFile, "format", ffrf_format, 0);
|
236
|
+
rb_define_method(cFFrubyFile, "streams", ffrf_streams, 0);
|
237
|
+
rb_define_method(cFFrubyFile, "video_streams", ffrf_video_streams, 0);
|
238
|
+
rb_define_method(cFFrubyFile, "audio_streams", ffrf_audio_streams, 0);
|
239
|
+
}
|
@@ -0,0 +1,196 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2007 James Le Cuirot
|
3
|
+
*
|
4
|
+
* This file is part of FFruby.
|
5
|
+
*
|
6
|
+
* FFruby is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* FFruby is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with FFmpeg; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#define _GNU_SOURCE
|
22
|
+
#include <ruby.h>
|
23
|
+
#include <ffmpeg/avformat.h>
|
24
|
+
#include <ffmpeg/avcodec.h>
|
25
|
+
|
26
|
+
VALUE cFFrubyStream;
|
27
|
+
VALUE cFFrubyVideoStream;
|
28
|
+
VALUE cFFrubyAudioStream;
|
29
|
+
|
30
|
+
static void ffrs_open_codec(AVStream* stream)
|
31
|
+
{
|
32
|
+
AVCodec *codec;
|
33
|
+
|
34
|
+
if (stream->codec->codec == NULL)
|
35
|
+
{
|
36
|
+
if ((codec = avcodec_find_decoder(stream->codec->codec_id)) == NULL)
|
37
|
+
rb_raise(rb_eIOError, "Cannot find codec!");
|
38
|
+
|
39
|
+
if (avcodec_open(stream->codec, codec) < 0)
|
40
|
+
rb_raise(rb_eIOError, "Cannot open codec!");
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
static AVStream* ffrs_get_stream(VALUE self)
|
45
|
+
{
|
46
|
+
AVStream *stream;
|
47
|
+
Data_Get_Struct(self, AVStream, stream);
|
48
|
+
return stream;
|
49
|
+
}
|
50
|
+
|
51
|
+
static VALUE ffrs_codec(VALUE self)
|
52
|
+
{
|
53
|
+
AVStream *stream = ffrs_get_stream(self);
|
54
|
+
ffrs_open_codec(stream);
|
55
|
+
return rb_str_new2(stream->codec->codec->name);
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE ffrs_tag(VALUE self)
|
59
|
+
{
|
60
|
+
char tag[4];
|
61
|
+
signed int i, j;
|
62
|
+
AVStream *stream = ffrs_get_stream(self);
|
63
|
+
|
64
|
+
i = stream->codec->codec_tag;
|
65
|
+
|
66
|
+
for (j = 3; j >= 0; j -= 1)
|
67
|
+
{
|
68
|
+
tag[j] = i >> (j * 8);
|
69
|
+
i -= tag[j] << (j * 8);
|
70
|
+
}
|
71
|
+
|
72
|
+
for (j = 3; j >= 0; j -= 1)
|
73
|
+
{
|
74
|
+
if (tag[j] != '\0')
|
75
|
+
break;
|
76
|
+
}
|
77
|
+
|
78
|
+
return rb_str_new(tag, j + 1);
|
79
|
+
}
|
80
|
+
|
81
|
+
static VALUE ffrs_bit_rate(VALUE self)
|
82
|
+
{
|
83
|
+
AVStream *stream = ffrs_get_stream(self);
|
84
|
+
return INT2NUM(stream->codec->bit_rate);
|
85
|
+
}
|
86
|
+
|
87
|
+
static VALUE ffrs_alloc(VALUE klass)
|
88
|
+
{
|
89
|
+
return Data_Wrap_Struct(klass, 0, 0, NULL);
|
90
|
+
}
|
91
|
+
|
92
|
+
static VALUE ffrs_initialize(VALUE self, VALUE file, VALUE index)
|
93
|
+
{
|
94
|
+
AVFormatContext *fmt;
|
95
|
+
AVStream *stream;
|
96
|
+
unsigned int i = FIX2UINT(index);
|
97
|
+
|
98
|
+
Data_Get_Struct(file, AVFormatContext, fmt);
|
99
|
+
|
100
|
+
if (i < 0 || i >= fmt->nb_streams)
|
101
|
+
rb_raise(rb_eIndexError, "Stream index out of range!");
|
102
|
+
|
103
|
+
DATA_PTR(self) = fmt->streams[i];
|
104
|
+
stream = ffrs_get_stream(self);
|
105
|
+
|
106
|
+
return self;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE ffrvs_width(VALUE self)
|
110
|
+
{
|
111
|
+
AVStream *stream = ffrs_get_stream(self);
|
112
|
+
return INT2NUM(stream->codec->width);
|
113
|
+
}
|
114
|
+
|
115
|
+
static VALUE ffrvs_height(VALUE self)
|
116
|
+
{
|
117
|
+
AVStream *stream = ffrs_get_stream(self);
|
118
|
+
return INT2NUM(stream->codec->height);
|
119
|
+
}
|
120
|
+
|
121
|
+
static VALUE ffrvs_frame_aspect_ratio(VALUE self)
|
122
|
+
{
|
123
|
+
AVStream *stream = ffrs_get_stream(self);
|
124
|
+
|
125
|
+
if (stream->codec->width == 0 || stream->codec->height == 0)
|
126
|
+
return Qnil;
|
127
|
+
else
|
128
|
+
return rb_funcall(rb_mKernel, rb_intern("Rational"), 2, INT2NUM(stream->codec->width), INT2NUM(stream->codec->height));
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE ffrvs_sample_aspect_ratio(VALUE self)
|
132
|
+
{
|
133
|
+
AVStream *stream = ffrs_get_stream(self);
|
134
|
+
|
135
|
+
if (stream->codec->sample_aspect_ratio.den == 0 || stream->codec->sample_aspect_ratio.num == 0)
|
136
|
+
return rb_funcall(rb_mKernel, rb_intern("Rational"), 2, INT2FIX(1), INT2FIX(1));
|
137
|
+
else
|
138
|
+
return rb_funcall(rb_mKernel, rb_intern("Rational"), 2, INT2NUM(stream->codec->sample_aspect_ratio.num), INT2NUM(stream->codec->sample_aspect_ratio.den));
|
139
|
+
}
|
140
|
+
|
141
|
+
static VALUE ffrvs_real_aspect_ratio(VALUE self)
|
142
|
+
{
|
143
|
+
VALUE x, y;
|
144
|
+
x = ffrvs_frame_aspect_ratio(self);
|
145
|
+
y = ffrvs_sample_aspect_ratio(self);
|
146
|
+
|
147
|
+
if (x == Qnil || y == Qnil)
|
148
|
+
return Qnil;
|
149
|
+
else
|
150
|
+
return rb_funcall(x, rb_intern("*"), 1, y);
|
151
|
+
}
|
152
|
+
|
153
|
+
static VALUE ffrvs_frame_rate(VALUE self)
|
154
|
+
{
|
155
|
+
AVStream *stream = ffrs_get_stream(self);
|
156
|
+
ffrs_open_codec(stream);
|
157
|
+
|
158
|
+
if (stream->r_frame_rate.den && stream->r_frame_rate.num)
|
159
|
+
return rb_funcall(rb_mKernel, rb_intern("Rational"), 2, INT2NUM(stream->r_frame_rate.num), INT2NUM(stream->r_frame_rate.den));
|
160
|
+
else
|
161
|
+
return rb_funcall(rb_mKernel, rb_intern("Rational"), 2, INT2NUM(stream->codec->time_base.den), INT2NUM(stream->codec->time_base.num));
|
162
|
+
}
|
163
|
+
|
164
|
+
static VALUE ffras_channels(VALUE self)
|
165
|
+
{
|
166
|
+
AVStream *stream = ffrs_get_stream(self);
|
167
|
+
return INT2FIX(stream->codec->channels);
|
168
|
+
}
|
169
|
+
|
170
|
+
static VALUE ffras_sample_rate(VALUE self)
|
171
|
+
{
|
172
|
+
AVStream *stream = ffrs_get_stream(self);
|
173
|
+
return INT2NUM(stream->codec->sample_rate);
|
174
|
+
}
|
175
|
+
|
176
|
+
void Init_ffrs()
|
177
|
+
{
|
178
|
+
cFFrubyStream = rb_define_class("FFrubyStream", rb_cObject);
|
179
|
+
rb_define_alloc_func(cFFrubyStream, ffrs_alloc);
|
180
|
+
rb_define_method(cFFrubyStream, "initialize", ffrs_initialize, 2);
|
181
|
+
rb_define_method(cFFrubyStream, "codec", ffrs_codec, 0);
|
182
|
+
rb_define_method(cFFrubyStream, "tag", ffrs_tag, 0);
|
183
|
+
rb_define_method(cFFrubyStream, "bit_rate", ffrs_bit_rate, 0);
|
184
|
+
|
185
|
+
cFFrubyVideoStream = rb_define_class("FFrubyVideoStream", cFFrubyStream);
|
186
|
+
rb_define_method(cFFrubyVideoStream, "width", ffrvs_width, 0);
|
187
|
+
rb_define_method(cFFrubyVideoStream, "height", ffrvs_height, 0);
|
188
|
+
rb_define_method(cFFrubyVideoStream, "frame_aspect_ratio", ffrvs_frame_aspect_ratio, 0);
|
189
|
+
rb_define_method(cFFrubyVideoStream, "sample_aspect_ratio", ffrvs_sample_aspect_ratio, 0);
|
190
|
+
rb_define_method(cFFrubyVideoStream, "real_aspect_ratio", ffrvs_real_aspect_ratio, 0);
|
191
|
+
rb_define_method(cFFrubyVideoStream, "frame_rate", ffrvs_frame_rate, 0);
|
192
|
+
|
193
|
+
cFFrubyAudioStream = rb_define_class("FFrubyAudioStream", cFFrubyStream);
|
194
|
+
rb_define_method(cFFrubyAudioStream, "channels", ffras_channels, 0);
|
195
|
+
rb_define_method(cFFrubyAudioStream, "sample_rate", ffras_sample_rate, 0);
|
196
|
+
}
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4.6
|
3
|
+
specification_version: 2
|
4
|
+
name: ffruby
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-11-06 00:00:00 -05:00
|
8
|
+
summary: a library that does something with media files!
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: wayneeseguin at gmail dot com
|
12
|
+
homepage: ffruby.rubyforge.org
|
13
|
+
rubyforge_project:
|
14
|
+
description: a library that does something with media files!
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: "0"
|
30
|
+
version:
|
31
|
+
platform: ruby
|
32
|
+
signing_key:
|
33
|
+
cert_chain: []
|
34
|
+
|
35
|
+
post_install_message:
|
36
|
+
authors:
|
37
|
+
- "ffruby: James Le Cuirot, gem: Wayne E. Seguin"
|
38
|
+
files:
|
39
|
+
- README
|
40
|
+
- Rakefile
|
41
|
+
- lib/ffruby
|
42
|
+
- lib/ffruby/version.rb
|
43
|
+
- ext/ffruby/ffruby.c
|
44
|
+
- ext/ffruby/ffrubyfile.c
|
45
|
+
- ext/ffruby/ffrubystream.c
|
46
|
+
- ext/ffruby/extconf.rb
|
47
|
+
test_files: []
|
48
|
+
|
49
|
+
rdoc_options:
|
50
|
+
- --quiet
|
51
|
+
- --title
|
52
|
+
- FFruby Reference
|
53
|
+
- --main
|
54
|
+
- README
|
55
|
+
- --inline-source
|
56
|
+
extra_rdoc_files:
|
57
|
+
- README
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions:
|
61
|
+
- ext/ffruby/extconf.rb
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
dependencies: []
|
65
|
+
|