ffmpeg-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,16 @@
1
+ Manifest
2
+ README.rdoc
3
+ Rakefile
4
+ ext/ffmpeg_ruby/conftest.dSYM/Contents/Info.plist
5
+ ext/ffmpeg_ruby/conftest.dSYM/Contents/Resources/DWARF/conftest
6
+ ext/ffmpeg_ruby/extconf.rb
7
+ ext/ffmpeg_ruby/ffmpeg_avcodec.c
8
+ ext/ffmpeg_ruby/ffmpeg_avcodec.h
9
+ ext/ffmpeg_ruby/ffmpeg_avformat.c
10
+ ext/ffmpeg_ruby/ffmpeg_avformat.h
11
+ ext/ffmpeg_ruby/ffmpeg_ruby.c
12
+ ext/ffmpeg_ruby/ffmpeg_ruby.h
13
+ ffmpeg-ruby.gemspec
14
+ lib/ffmpeg-ruby.rb
15
+ tasks/mac_specific.rake
16
+ test/test.rb
data/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ = Ruby FFMpeg Library
2
+
3
+ "ffmpeg-ruby" is a ruby gem library (work in progress) that provides bindings allowing you to access the ffmpeg under ruby. FFMpeg is a cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library.
4
+
5
+ This implementation is starting by doing the translation for some of the functions in libavcodec and libavformat to ruby.
6
+
7
+ FFMpeg is provided by http://ffmpeg.org/ under the LGPL license.
8
+
9
+ This bindings gem is graciously provided by http://www.channels.com under the LGPL license.
10
+
11
+ == Installing
12
+
13
+ $ gem install ffmpeg-ruby
14
+
15
+ == Installation troubleshooting
16
+
17
+ If you run into trouble, it could be the C bundle not building. This is known to happen on MacOS 64-bit or with the ffmpeg from macports. You basically need to run ruby extconf yourself then.
18
+
19
+
20
+ $ ruby extconf.rb
21
+
22
+ You may need to add +--with+ on mac, to point it to macports' /opt/local for the libraries.
23
+
24
+ This has worked on my snow leopard machine:
25
+
26
+ $ sudo port install ffmpeg
27
+ (go have coffee)
28
+ $ env ARCHFLAGS="-arch x86_64" ruby extconf.rb --with-avformat-dir=/opt/local
29
+ make
30
+
31
+ This will provide you with a bundle you can require.
32
+
33
+ == Usage
34
+
35
+ See the code on +test/+ for usage. But basically it goes like this:
36
+
37
+ require 'ffmpeg-ruby'
38
+
39
+ # Get a list of the video codecs supported
40
+ FFMpeg::AVCodec.supported_video_codecs
41
+
42
+ # Get a list of the audio codecs supported
43
+ FFMpeg::AVCodec.supported_video_codecs
44
+
45
+ # Create new AVFormatContext
46
+ f = FFMpeg::AVFormatContext.new("/path/to/my/video.mov")
47
+
48
+ f.codec_contexts.each{ |ctx|
49
+ puts ctx.name # The name of the codec this file uses.
50
+ }
51
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new("ffmpeg-ruby", "0.1.0") do |p|
6
+ p.description = "FFMpeg Ruby Bridge. Call FFMpeg/LibAVCodec/LibAVFormat directly"
7
+ p.url = "http://github.com/hackerdude/ffmpeg-ruby"
8
+ p.author = "David Martinez"
9
+ p.ignore_pattern = ["tmp/*", "script/*"]
10
+ p.development_dependencies = [] # TODO How to do native dependencies?
11
+ end
12
+
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each{|ext| load ext }
15
+
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>English</string>
7
+ <key>CFBundleIdentifier</key>
8
+ <string>com.apple.xcode.dsym.conftest</string>
9
+ <key>CFBundleInfoDictionaryVersion</key>
10
+ <string>6.0</string>
11
+ <key>CFBundlePackageType</key>
12
+ <string>dSYM</string>
13
+ <key>CFBundleSignature</key>
14
+ <string>????</string>
15
+ <key>CFBundleShortVersionString</key>
16
+ <string>1.0</string>
17
+ <key>CFBundleVersion</key>
18
+ <string>1</string>
19
+ </dict>
20
+ </plist>
@@ -0,0 +1,26 @@
1
+ require 'mkmf'
2
+ #require 'rubygems'
3
+ #require 'ruby-debug'
4
+ #Debugger.start
5
+
6
+ def boom(v)
7
+ puts(v)
8
+ exit 1
9
+ end
10
+
11
+ #debugger
12
+ if RUBY_PLATFORM == "universal-darwin10.0"
13
+ # TODO Set the archflags to -arch x86_64 ONLY if it's a 64-bit snow leopard machine.
14
+ #ENV['ARCHFLAGS'] = "-arch i386 -arch x86_64"
15
+ $CFLAGS.sub!("-arch x86_64", "")
16
+ end
17
+ unless ( have_header("libavformat/avformat.h") ||
18
+ find_header("libavformat/avformat.h", "/opt/local/include", "/usr/local/include", "/usr/include") ) and
19
+ ( have_library("avformat", "av_register_all") or
20
+ find_library("avformat", "av_register_all", "/opt/local/lib", "/usr/local/lib", "/usr/lib") )
21
+ boom(<<EOL)
22
+ You need to install or tell me where to find ffmpeg. Check the mkmf.log file to see what erred out.
23
+ EOL
24
+ end
25
+
26
+ create_makefile("ffmpeg_ruby")
@@ -0,0 +1,199 @@
1
+ #include "ruby.h"
2
+ #include <libavcodec/avcodec.h>
3
+
4
+ VALUE cFFMpegAVCodec;
5
+ VALUE cFFMpegAVCodecContext;
6
+
7
+ void AVCodec_mark(void *v) {}
8
+ void AVCodec_free(void *v) {}
9
+
10
+ void AVCodecContext_mark(AVCodecContext v) {}
11
+ void AVCodecContext_free(AVCodecContext v) {
12
+ }
13
+
14
+ VALUE AVCodecContext_codec_type(VALUE self)
15
+ {
16
+ AVCodecContext *ptr;
17
+ Data_Get_Struct(self, AVCodecContext, ptr);
18
+ VALUE result = INT2NUM(ptr->codec_type);
19
+ return result;
20
+ }
21
+
22
+ VALUE codec_type_map()
23
+ {
24
+ VALUE result = rb_hash_new();
25
+ rb_hash_aset(result, INT2NUM(CODEC_TYPE_VIDEO), rb_str_new2("Video"));
26
+ rb_hash_aset(result, INT2NUM(CODEC_TYPE_AUDIO), rb_str_new2("Audio"));
27
+ rb_hash_aset(result, INT2NUM(CODEC_TYPE_DATA), rb_str_new2("Data"));
28
+ rb_hash_aset(result, INT2NUM(CODEC_TYPE_SUBTITLE), rb_str_new2("Subtitle"));
29
+ rb_hash_aset(result, INT2NUM(CODEC_TYPE_ATTACHMENT), rb_str_new2("Attachment"));
30
+ return result;
31
+ }
32
+
33
+
34
+ VALUE AVCodecContext_codec_id(VALUE self)
35
+ {
36
+ AVCodecContext *ptr;
37
+ Data_Get_Struct(self, AVCodecContext, ptr);
38
+ VALUE result = INT2NUM(ptr->codec_id);
39
+ return result;
40
+ }
41
+
42
+ VALUE AVCodecContext_width(VALUE self)
43
+ {
44
+ AVCodecContext *ptr;
45
+ Data_Get_Struct(self, AVCodecContext, ptr);
46
+ VALUE result = INT2NUM(ptr->width);
47
+ return result;
48
+ }
49
+
50
+ VALUE AVCodecContext_height(VALUE self)
51
+ {
52
+ AVCodecContext *ptr;
53
+ Data_Get_Struct(self, AVCodecContext, ptr);
54
+ VALUE result = INT2NUM(ptr->height);
55
+ return result;
56
+ }
57
+
58
+ VALUE AVCodecContext_channels(VALUE self)
59
+ {
60
+ AVCodecContext *ptr;
61
+ Data_Get_Struct(self, AVCodecContext, ptr);
62
+ VALUE result = INT2NUM(ptr->channels);
63
+ return result;
64
+ }
65
+
66
+ VALUE AVCodecContext_sample_rate(VALUE self)
67
+ {
68
+ AVCodecContext *ptr;
69
+ Data_Get_Struct(self, AVCodecContext, ptr);
70
+ VALUE result = INT2NUM(ptr->sample_rate);
71
+ return result;
72
+ }
73
+
74
+ VALUE AVCodec_long_name(VALUE self)
75
+ {
76
+ char* tm;
77
+ AVCodec *ptr;
78
+ Data_Get_Struct(self, AVCodec, ptr);
79
+ tm = ptr->long_name;
80
+ return rb_str_new2(tm);
81
+ }
82
+
83
+ VALUE AVCodec_name(VALUE self)
84
+ {
85
+ char* tm;
86
+ AVCodec *ptr;
87
+ Data_Get_Struct(self, AVCodec, ptr);
88
+ tm = ptr->name;
89
+ return rb_str_new2(tm);
90
+ }
91
+
92
+ VALUE AVCodec_codec_type(VALUE self)
93
+ {
94
+ char* tm;
95
+ AVCodec *ptr;
96
+ Data_Get_Struct(self, AVCodec, ptr);
97
+ return INT2NUM(ptr->type);
98
+ }
99
+
100
+ VALUE AVCodecContext_codec_long_name(VALUE self)
101
+ {
102
+ char* tm;
103
+ AVCodecContext *ptr;
104
+ Data_Get_Struct(self, AVCodecContext, ptr);
105
+ if (ptr->codec == NULL)
106
+ return Qnil;
107
+ tm = ptr->codec->long_name;
108
+ return rb_str_new2(tm);
109
+ }
110
+
111
+ VALUE AVCodecContext_codec_name(VALUE self)
112
+ {
113
+ char* tm;
114
+ AVCodecContext *ptr;
115
+ Data_Get_Struct(self, AVCodecContext, ptr);
116
+ if (ptr->codec == NULL)
117
+ return Qnil;
118
+ tm = ptr->codec->name;
119
+ return rb_str_new2(tm);
120
+ }
121
+
122
+ VALUE supported_avcodecs()
123
+ {
124
+ VALUE result = rb_hash_new();
125
+ AVCodec *pNextCodec = NULL;
126
+ pNextCodec = av_codec_next(pNextCodec);
127
+ while (pNextCodec != NULL) {
128
+ VALUE sNextCodecName = rb_str_new2(pNextCodec->name);
129
+ //VALUE sNextCodecLongName = rb_str_new2(pNextCodec->long_name);
130
+ VALUE codec = Data_Wrap_Struct(cFFMpegAVCodec, AVCodecContext_mark, AVCodecContext_free, pNextCodec);
131
+ rb_hash_aset(result, sNextCodecName, codec);
132
+ pNextCodec = av_codec_next(pNextCodec);
133
+ }
134
+ return result;
135
+ }
136
+
137
+ VALUE supported_video_codecs()
138
+ {
139
+ VALUE result = rb_hash_new();
140
+ AVCodec *pNextCodec = NULL;
141
+ pNextCodec = av_codec_next(pNextCodec);
142
+ while (pNextCodec != NULL) {
143
+ if (pNextCodec->type==CODEC_TYPE_VIDEO) {
144
+ VALUE sNextCodecName = rb_str_new2(pNextCodec->name);
145
+ //VALUE sNextCodecLongName = rb_str_new2(pNextCodec->long_name);
146
+ VALUE codec = Data_Wrap_Struct(cFFMpegAVCodec, AVCodecContext_mark, AVCodecContext_free, pNextCodec);
147
+ rb_hash_aset(result, sNextCodecName, codec);
148
+ }
149
+ pNextCodec = av_codec_next(pNextCodec);
150
+ }
151
+ return result;
152
+ }
153
+
154
+ VALUE supported_audio_codecs()
155
+ {
156
+ VALUE result = rb_hash_new();
157
+ AVCodec *pNextCodec = NULL;
158
+ pNextCodec = av_codec_next(pNextCodec);
159
+ while (pNextCodec != NULL) {
160
+ if (pNextCodec->type==CODEC_TYPE_AUDIO) {
161
+ VALUE sNextCodecName = rb_str_new2(pNextCodec->name);
162
+ //VALUE sNextCodecLongName = rb_str_new2(pNextCodec->long_name);
163
+ VALUE codec = Data_Wrap_Struct(cFFMpegAVCodec, AVCodecContext_mark, AVCodecContext_free, pNextCodec);
164
+ rb_hash_aset(result, sNextCodecName, codec);
165
+ }
166
+ pNextCodec = av_codec_next(pNextCodec);
167
+ }
168
+ return result;
169
+ }
170
+
171
+ void Init_ffmpeg_ruby_avcodec(VALUE module)
172
+ {
173
+
174
+ cFFMpegAVCodec = rb_define_class_under(module, "AVCodec", rb_cObject);
175
+ rb_define_method(cFFMpegAVCodec, "name", AVCodec_name, 0);
176
+ rb_define_method(cFFMpegAVCodec, "long_name", AVCodec_long_name, 0);
177
+ rb_define_method(cFFMpegAVCodec, "codec_type", AVCodec_codec_type, 0);
178
+ rb_define_singleton_method(cFFMpegAVCodec, "supported_avcodecs", supported_avcodecs, 0);
179
+ rb_define_singleton_method(cFFMpegAVCodec, "supported_video_codecs", supported_video_codecs, 0);
180
+ rb_define_singleton_method(cFFMpegAVCodec, "supported_audio_codecs", supported_audio_codecs, 0);
181
+ cFFMpegAVCodecContext = rb_define_class_under(module, "AVCodecContext", rb_cObject);
182
+ rb_define_method(cFFMpegAVCodecContext, "long_name", AVCodecContext_codec_long_name, 0);
183
+ rb_define_method(cFFMpegAVCodecContext, "name", AVCodecContext_codec_name, 0);
184
+ rb_define_method(cFFMpegAVCodecContext, "codec_type", AVCodecContext_codec_type, 0);
185
+ rb_define_method(cFFMpegAVCodecContext, "codec_id", AVCodecContext_codec_id, 0);
186
+ rb_define_method(cFFMpegAVCodecContext, "width", AVCodecContext_width, 0);
187
+ rb_define_method(cFFMpegAVCodecContext, "height", AVCodecContext_height, 0);
188
+ rb_define_method(cFFMpegAVCodecContext, "channels", AVCodecContext_channels, 0);
189
+ rb_define_method(cFFMpegAVCodecContext, "sample_rate", AVCodecContext_sample_rate, 0);
190
+
191
+ // Codec Types, for AVCodecContext
192
+ rb_define_const(module, "CODEC_TYPE_VIDEO", INT2NUM(CODEC_TYPE_VIDEO));
193
+ rb_define_const(module, "CODEC_TYPE_AUDIO", INT2NUM(CODEC_TYPE_AUDIO));
194
+ rb_define_const(module, "CODEC_TYPE_DATA", INT2NUM(CODEC_TYPE_DATA));
195
+ rb_define_const(module, "CODEC_TYPE_SUBTITLE", INT2NUM(CODEC_TYPE_SUBTITLE));
196
+ rb_define_const(module, "CODEC_TYPE_ATTACHMENT", INT2NUM(CODEC_TYPE_ATTACHMENT));
197
+ rb_define_const(module, "MAP_CODEC_TYPES", codec_type_map());
198
+
199
+ }
@@ -0,0 +1,27 @@
1
+ VALUE cFFMpegAVCodecContext;
2
+
3
+ void Init_ffmpeg_ruby_avcodec(VALUE module)
4
+
5
+ void AVCodec_mark(void *v);
6
+ void AVCodec_free(void *v);
7
+
8
+ void AVCodecContext_mark(AVCodecContext v);
9
+ void AVCodecContext_free(AVCodecContext v);
10
+
11
+ VALUE AVCodecContext_codec_type(VALUE self);
12
+ VALUE codec_type_map();
13
+
14
+ VALUE AVCodecContext_codec_id(VALUE self);
15
+ VALUE AVCodecContext_width(VALUE self);
16
+ VALUE AVCodecContext_height(VALUE self);
17
+ VALUE AVCodecContext_channels(VALUE self);
18
+ VALUE AVCodecContext_sample_rate(VALUE self);
19
+ VALUE AVCodec_long_name(VALUE self);
20
+ VALUE AVCodec_name(VALUE self);
21
+ VALUE AVCodec_codec_type(VALUE self);
22
+ VALUE AVCodecContext_codec_long_name(VALUE self);
23
+ VALUE AVCodecContext_codec_name(VALUE self);
24
+ VALUE supported_avcodecs();
25
+ VALUE supported_video_codecs();
26
+ VALUE supported_audio_codecs();
27
+
@@ -0,0 +1,149 @@
1
+ #include "ruby.h"
2
+ #include <libavformat/avformat.h>
3
+ #include "ffmpeg_avformat.h"
4
+
5
+ void AVFormatContext_mark(void *v) {}
6
+
7
+ void AVFormatContext_free(void *v) {
8
+ // TODO Figure out how to avoid double-closing.
9
+ //AVFormatContext* f = (AVFormatContext*)v;
10
+ //if (f->filename != NULL)
11
+ //av_close_input_file(v);
12
+ }
13
+
14
+ void AVOutputFormat_mark(void *v){}
15
+ void AVOutputFormat_free(void *v){}
16
+
17
+ VALUE supported_avformats()
18
+ {
19
+ VALUE result = rb_hash_new();
20
+ AVOutputFormat *pNext = NULL;
21
+ pNext = av_oformat_next(pNext);
22
+ while (pNext != NULL) {
23
+ VALUE sNextFormatName = rb_str_new2(pNext->name);
24
+ //VALUE sNextLongName = rb_str_new2(pNext->long_name);
25
+ VALUE format = Data_Wrap_Struct(cFFMpegAVOutputFormat, AVOutputFormat_mark, AVOutputFormat_free, pNext);
26
+ rb_obj_call_init(result, 0, 0);
27
+ rb_hash_aset(result, sNextFormatName, format);
28
+ pNext = av_codec_next(pNext);
29
+ }
30
+ return result;
31
+ }
32
+
33
+
34
+ VALUE AVFormatContext_dump_format(VALUE self) {
35
+ AVFormatContext *ptr;
36
+ Data_Get_Struct(self, AVFormatContext, ptr);
37
+ dump_format(ptr, 0, ptr->filename, 0);
38
+ return Qnil;
39
+ }
40
+ VALUE AVFormatContext_duration(VALUE self) {
41
+ AVFormatContext *ptr;
42
+ Data_Get_Struct(self, AVFormatContext, ptr);
43
+ //ptr->filename = NULL;
44
+ return INT2NUM(ptr->duration);
45
+ }
46
+ VALUE AVFormatContext_close_file(VALUE self) {
47
+ AVFormatContext *ptr;
48
+ Data_Get_Struct(self, AVFormatContext, ptr);
49
+ av_close_input_file(ptr);
50
+ //ptr->filename = NULL;
51
+ return Qnil;
52
+ }
53
+ VALUE AVFormatContext_new(VALUE klaas, VALUE ruby_filename) {
54
+ Check_Type(ruby_filename, T_STRING);
55
+ char* filename = StringValuePtr(ruby_filename);
56
+
57
+ AVFormatContext *pFormatCtx;
58
+ // Open video file
59
+ if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
60
+ rb_raise(rb_eRuntimeError, "Could not open video file %s", filename);
61
+ return NULL;
62
+ }
63
+
64
+ // Retrieve stream information
65
+ if(av_find_stream_info(pFormatCtx)<0) {
66
+ rb_raise(rb_eRuntimeError, "Could find the stream information in file %s", filename);
67
+ return NULL; // Couldn't find stream information
68
+ }
69
+
70
+ VALUE result = Data_Wrap_Struct(klaas, AVFormatContext_mark, AVFormatContext_free, pFormatCtx);
71
+ rb_obj_call_init(result, 0, 0);
72
+ return result;
73
+ }
74
+
75
+ /* Return all the AVCodecContext entries for all streams in the file */
76
+ VALUE AVFormatContext_codec_contexts(VALUE self) {
77
+ AVFormatContext *ptr;
78
+ Data_Get_Struct(self, AVFormatContext, ptr);
79
+ VALUE result = rb_ary_new();
80
+ int i, videoStream;
81
+ videoStream=-1;
82
+ for(i=0; i<ptr->nb_streams; i++) {
83
+ // Get a pointer to the codec context for the video stream
84
+ AVCodecContext *pCodecCtx = ptr->streams[i]->codec;
85
+ AVCodec *pCodec;
86
+ pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
87
+ pCodecCtx->codec = pCodec;
88
+
89
+ // Turn it into something ruby can understand
90
+ VALUE rCodec = Data_Wrap_Struct(cFFMpegAVCodecContext, AVCodecContext_mark, AVCodecContext_free, pCodecCtx);
91
+ rb_obj_call_init(rCodec,0,0);
92
+ rb_ary_push(result, rCodec);
93
+ }
94
+ //if(videoStream==-1) {
95
+ //rb_raise(rb_eRuntimeError, "No video streams here!");
96
+ //return Qnil;
97
+ //}
98
+ return result;
99
+ }
100
+
101
+ VALUE AVFormatContext_title(VALUE self) {
102
+ AVFormatContext *ptr;
103
+ Data_Get_Struct(self, AVFormatContext, ptr);
104
+ return rb_str_new2(ptr->title);
105
+ }
106
+
107
+ VALUE AVFormatContext_author(VALUE self) {
108
+ AVFormatContext *ptr;
109
+ Data_Get_Struct(self, AVFormatContext, ptr);
110
+ return rb_str_new2(ptr->author);
111
+ }
112
+
113
+ VALUE AVFormatContext_copyright(VALUE self) {
114
+ AVFormatContext *ptr;
115
+ Data_Get_Struct(self, AVFormatContext, ptr);
116
+ return rb_str_new2(ptr->copyright);
117
+ }
118
+
119
+ VALUE AVFormatContext_bit_rate(VALUE self) {
120
+ AVFormatContext *ptr;
121
+ Data_Get_Struct(self, AVFormatContext, ptr);
122
+ return INT2NUM(ptr->bit_rate);
123
+ }
124
+
125
+ VALUE AVFormatContext_album(VALUE self) {
126
+ AVFormatContext *ptr;
127
+ Data_Get_Struct(self, AVFormatContext, ptr);
128
+ return rb_str_new2(ptr->album);
129
+ }
130
+
131
+
132
+ void Init_ffmpeg_ruby_avformat(VALUE module)
133
+ {
134
+
135
+ cFFMpegAVFormatContext = rb_define_class_under(module, "AVFormatContext", rb_cObject);
136
+ rb_define_singleton_method(cFFMpegAVFormatContext, "new", AVFormatContext_new, 1);
137
+ rb_define_method(cFFMpegAVFormatContext, "close_file", AVFormatContext_close_file, 0);
138
+ rb_define_method(cFFMpegAVFormatContext, "duration", AVFormatContext_duration, 0);
139
+ rb_define_method(cFFMpegAVFormatContext, "title", AVFormatContext_title, 0);
140
+ rb_define_method(cFFMpegAVFormatContext, "copyright", AVFormatContext_copyright, 0);
141
+ rb_define_method(cFFMpegAVFormatContext, "author", AVFormatContext_author, 0);
142
+ rb_define_method(cFFMpegAVFormatContext, "album", AVFormatContext_album, 0);
143
+ rb_define_method(cFFMpegAVFormatContext, "bit_rate", AVFormatContext_bit_rate, 0);
144
+ rb_define_method(cFFMpegAVFormatContext, "codec_contexts", AVFormatContext_codec_contexts, 0);
145
+ rb_define_method(cFFMpegAVFormatContext, "dump_format", AVFormatContext_dump_format, 0);
146
+
147
+ cFFMpegAVOutputFormat = rb_define_class_under(module, "AVOutputFormat", rb_cObject);
148
+ rb_define_singleton_method(cFFMpegAVOutputFormat, "supported_avformats", supported_avformats, 0);
149
+ }
@@ -0,0 +1,28 @@
1
+ #include <libavformat/avformat.h>
2
+ #include <ruby.h>
3
+
4
+ VALUE cFFMpegAVFormatContext;
5
+ VALUE cFFMpegAVOutputFormat;
6
+
7
+ void AVOutputFormat_mark(void *v);
8
+ void AVOutputFormat_free(void *v);
9
+
10
+ void AVFormatContext_mark(void *v);
11
+ void AVFormatContext_free(void *v);
12
+
13
+ VALUE AVFormatContext_dump_format(VALUE);
14
+ VALUE AVFormatContext_duration(VALUE);
15
+ VALUE AVFormatContext_close_file(VALUE);
16
+ VALUE AVFormatContext_new(VALUE, VALUE);
17
+ VALUE AVFormatContext_codec_contexts(VALUE);
18
+ VALUE AVFormatContext_title(VALUE);
19
+ VALUE AVFormatContext_author(VALUE);
20
+ VALUE AVFormatContext_copyright(VALUE);
21
+ VALUE AVFormatContext_bit_rate(VALUE);
22
+ VALUE AVFormatContext_album(VALUE);
23
+ void Init_ffmpeg_ruby_avformat(VALUE module);
24
+
25
+ // Forward declaring some necessary avcodec stuff
26
+ void AVCodecContext_mark(void *v);
27
+ void AVCodecContext_free(void *v);
28
+ extern VALUE cFFMpegAVCodecContext;
@@ -0,0 +1,16 @@
1
+ #include "ffmpeg_ruby.h"
2
+
3
+ #include <libavcodec/avcodec.h>
4
+ #include <libavformat/avformat.h>
5
+
6
+ /** FFMpeg Module */
7
+ VALUE mFFMpeg;
8
+ /** *** Ruby Interface *** **/
9
+ void Init_ffmpeg_ruby()
10
+ {
11
+ av_register_all();
12
+ mFFMpeg = rb_define_module("FFMpeg");
13
+ Init_ffmpeg_ruby_avcodec(mFFMpeg);
14
+ Init_ffmpeg_ruby_avformat(mFFMpeg);
15
+ }
16
+
@@ -0,0 +1,3 @@
1
+ #include "ruby.h"
2
+
3
+
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ffmpeg-ruby}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["David Martinez"]
9
+ s.date = %q{2010-02-10}
10
+ s.description = %q{FFMpeg Ruby Bridge. Call FFMpeg/LibAVCodec/LibAVFormat directly}
11
+ s.email = %q{}
12
+ s.extensions = ["ext/ffmpeg_ruby/extconf.rb"]
13
+ s.extra_rdoc_files = ["README.rdoc", "ext/ffmpeg_ruby/conftest.dSYM/Contents/Info.plist", "ext/ffmpeg_ruby/conftest.dSYM/Contents/Resources/DWARF/conftest", "ext/ffmpeg_ruby/extconf.rb", "ext/ffmpeg_ruby/ffmpeg_avcodec.c", "ext/ffmpeg_ruby/ffmpeg_avcodec.h", "ext/ffmpeg_ruby/ffmpeg_avformat.c", "ext/ffmpeg_ruby/ffmpeg_avformat.h", "ext/ffmpeg_ruby/ffmpeg_ruby.c", "ext/ffmpeg_ruby/ffmpeg_ruby.h", "lib/ffmpeg-ruby.rb", "tasks/mac_specific.rake"]
14
+ s.files = ["Manifest", "README.rdoc", "Rakefile", "ext/ffmpeg_ruby/conftest.dSYM/Contents/Info.plist", "ext/ffmpeg_ruby/conftest.dSYM/Contents/Resources/DWARF/conftest", "ext/ffmpeg_ruby/extconf.rb", "ext/ffmpeg_ruby/ffmpeg_avcodec.c", "ext/ffmpeg_ruby/ffmpeg_avcodec.h", "ext/ffmpeg_ruby/ffmpeg_avformat.c", "ext/ffmpeg_ruby/ffmpeg_avformat.h", "ext/ffmpeg_ruby/ffmpeg_ruby.c", "ext/ffmpeg_ruby/ffmpeg_ruby.h", "ffmpeg-ruby.gemspec", "lib/ffmpeg-ruby.rb", "tasks/mac_specific.rake", "test/test.rb"]
15
+ s.homepage = %q{http://github.com/hackerdude/ffmpeg-ruby}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ffmpeg-ruby", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib", "ext"]
18
+ s.rubyforge_project = %q{ffmpeg-ruby}
19
+ s.rubygems_version = %q{1.3.5}
20
+ s.summary = %q{FFMpeg Ruby Bridge. Call FFMpeg/LibAVCodec/LibAVFormat directly}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ # Load the C library.
2
+ $:.unshift "#{File.dirname(__FILE__)}/../ext/ffmpeg_ruby/"
3
+
4
+ require "ffmpeg_ruby"
@@ -0,0 +1,9 @@
1
+ task :compile_mac do
2
+ puts "Compiling on a mac"
3
+ `cd ext/ffmpeg_ruby && env ARCHFLAGS="-arch x86_64" ruby extconf.rb --with-avformat-dir=/opt/local && make`
4
+ end
5
+
6
+ task :clean_mac => :clean do
7
+ puts "Cleaning on a mac"
8
+ `rm -rf ext/ffmpeg_ruby/conftest.dSYM`
9
+ end
data/test/test.rb ADDED
@@ -0,0 +1,39 @@
1
+ require "#{File.dirname(__FILE__)}/../lib/ffmpeg-ruby"
2
+
3
+ puts "Here are the video codecs I support, of the #{FFMpeg::AVCodec.supported_avcodecs.length} codecs:"
4
+ FFMpeg::AVCodec.supported_video_codecs.each{|k,v|
5
+ puts " - #{k}=#{v.long_name} (#{v.name}) of type #{FFMpeg::MAP_CODEC_TYPES[v.codec_type]}"
6
+ }
7
+
8
+ FFMpeg::AVCodec.supported_audio_codecs.each{|k,v|
9
+ puts " - #{k}=#{v.long_name} (#{v.name}) of type #{FFMpeg::MAP_CODEC_TYPES[v.codec_type]}"
10
+ }
11
+ puts "Creating new AVFormatContext"
12
+ filename = '/Users/david/channels-reader/public/videos/Channels_Playlist_WEB.mov'
13
+ if ARGV.length > 0
14
+ filename = ARGV[0]
15
+ end
16
+ f = FFMpeg::AVFormatContext.new(filename)
17
+ "Format Information:"
18
+ puts " Duration: #{f.duration}"
19
+ puts " Title: #{f.title}"
20
+ puts " Copyright: #{f.copyright}"
21
+ puts " Author: #{f.author}"
22
+ puts " Album: #{f.album}"
23
+ puts " Bit Rate: #{f.bit_rate}"
24
+
25
+ puts "\nCodec Information for #{filename}"
26
+ f.codec_contexts.each_with_index{|ctx,i|
27
+ puts "Codec info for stream ##{i}"
28
+ puts " Type: #{ctx.codec_type} (#{FFMpeg::MAP_CODEC_TYPES[ctx.codec_type]})"
29
+ puts " Name: #{ctx.name}"
30
+ puts " Long Name: #{ctx.long_name}"
31
+ puts " Width: #{ctx.width}"
32
+ puts " Height: #{ctx.height}"
33
+ puts " Audio Channels: #{ctx.channels}"
34
+ puts " Audio Sample Rate: #{ctx.sample_rate}"
35
+ }
36
+
37
+ puts "-- Now dumping the format:"
38
+ f.dump_format
39
+
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffmpeg-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Martinez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-10 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: FFMpeg Ruby Bridge. Call FFMpeg/LibAVCodec/LibAVFormat directly
17
+ email: ""
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/ffmpeg_ruby/extconf.rb
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - ext/ffmpeg_ruby/conftest.dSYM/Contents/Info.plist
25
+ - ext/ffmpeg_ruby/conftest.dSYM/Contents/Resources/DWARF/conftest
26
+ - ext/ffmpeg_ruby/extconf.rb
27
+ - ext/ffmpeg_ruby/ffmpeg_avcodec.c
28
+ - ext/ffmpeg_ruby/ffmpeg_avcodec.h
29
+ - ext/ffmpeg_ruby/ffmpeg_avformat.c
30
+ - ext/ffmpeg_ruby/ffmpeg_avformat.h
31
+ - ext/ffmpeg_ruby/ffmpeg_ruby.c
32
+ - ext/ffmpeg_ruby/ffmpeg_ruby.h
33
+ - lib/ffmpeg-ruby.rb
34
+ - tasks/mac_specific.rake
35
+ files:
36
+ - Manifest
37
+ - README.rdoc
38
+ - Rakefile
39
+ - ext/ffmpeg_ruby/conftest.dSYM/Contents/Info.plist
40
+ - ext/ffmpeg_ruby/conftest.dSYM/Contents/Resources/DWARF/conftest
41
+ - ext/ffmpeg_ruby/extconf.rb
42
+ - ext/ffmpeg_ruby/ffmpeg_avcodec.c
43
+ - ext/ffmpeg_ruby/ffmpeg_avcodec.h
44
+ - ext/ffmpeg_ruby/ffmpeg_avformat.c
45
+ - ext/ffmpeg_ruby/ffmpeg_avformat.h
46
+ - ext/ffmpeg_ruby/ffmpeg_ruby.c
47
+ - ext/ffmpeg_ruby/ffmpeg_ruby.h
48
+ - ffmpeg-ruby.gemspec
49
+ - lib/ffmpeg-ruby.rb
50
+ - tasks/mac_specific.rake
51
+ - test/test.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/hackerdude/ffmpeg-ruby
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --line-numbers
59
+ - --inline-source
60
+ - --title
61
+ - Ffmpeg-ruby
62
+ - --main
63
+ - README.rdoc
64
+ require_paths:
65
+ - lib
66
+ - ext
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "1.2"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project: ffmpeg-ruby
82
+ rubygems_version: 1.3.5
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: FFMpeg Ruby Bridge. Call FFMpeg/LibAVCodec/LibAVFormat directly
86
+ test_files: []
87
+