ffmpeg-ruby 0.1.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/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
+