yamdi 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ == 0.1.2 (January 28, 2011)
2
+
3
+ * Move key frames into a class of their own. [Bob Burbach]
4
+ * Update documentation and provide example rake task for refreshing metadata. [Bob Burbach]
5
+
1
6
  == 0.1.1 (January 25, 2011)
2
7
 
3
8
  * Fix errant require that caused gem to fail but tests to pass. [Bob Burbach]
@@ -6,6 +6,8 @@ The Yamdi command line tool expects to receive a path to an flv file and will re
6
6
 
7
7
  The current gem version only supports the reading of metadata. The command line tool also supports the writing of the metadata into a new .flv file but this is not yet supported in this gem.
8
8
 
9
+ Tested under ruby 1.8.7 and 1.9.2
10
+
9
11
 
10
12
  == Usage
11
13
 
@@ -24,6 +26,20 @@ You can also use Yamdi in a Paperclip processor. I've provided a simple example
24
26
 
25
27
  This is useful for adding things like video duration to your db when a user uploads a video.
26
28
 
29
+ class Video
30
+ has_attached_file :video,
31
+ :styles => {:orginal => {}},
32
+ :processors => [:metadata_extractor]
33
+ end
34
+
35
+ Be sure you add the styles hash even if it is empty as above or your paperclip processors won't run.
36
+
37
+ === Refreshing Exisitng Videos
38
+
39
+ Perhaps you're adding yamdi to your current set up, want to refresh the data in your models or add a new column to present to your users.
40
+
41
+ This is easily accomplished of you are using Paperclip. I've added an example rake task in lib/tasks/metadata_refresh.rake
42
+
27
43
  == Supported methods
28
44
 
29
45
  duration :: float, in seconds
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -0,0 +1,41 @@
1
+ require 'nokogiri'
2
+
3
+ class KeyFrame
4
+
5
+ attr_accessor :time, :file_position
6
+
7
+ def initialize(options = {})
8
+ @time = options[:time]
9
+ @file_position = options[:file_position]
10
+ end
11
+
12
+ def self.all_from_xml(keyframe_xml)
13
+ times = get_times(keyframe_xml.xpath("//times/value"))
14
+ file_positions = get_file_positions(keyframe_xml.xpath("//filepositions/value"))
15
+
16
+ count = 0
17
+ key_frames = []
18
+ while count < times.size do
19
+ key_frames << KeyFrame.new(:time => times[count], :file_position => file_positions[count])
20
+ count = count + 1
21
+ end
22
+
23
+ key_frames
24
+ end
25
+
26
+ def self.get_times(times_data_xml)
27
+ times = []
28
+ times_data_xml.children.each do |el|
29
+ times << el.inner_text.to_f
30
+ end
31
+ times
32
+ end
33
+
34
+ def self.get_file_positions(file_positions_xml)
35
+ file_positions = []
36
+ file_positions_xml.children.each do |el|
37
+ file_positions << el.inner_text.to_i
38
+ end
39
+ file_positions
40
+ end
41
+ end
@@ -1,3 +1,16 @@
1
+ # This assumes that you are using paperclip.
2
+ # For example you may Video model with an attachment of video.
3
+ # truncated example:
4
+ # class Video
5
+ # has_attached_file :video,
6
+ # :styles => {:orginal => {}},
7
+ # :processors => [:metadata_extractor]
8
+ # end
9
+ #
10
+ # Remember for processors to work you must define styles on
11
+ # has_attached_file. Even if they are just blank as the example
12
+ # above. Without them processors won't be triggered.
13
+
1
14
  module Paperclip
2
15
  class MetadataExtractor < Paperclip::Processor
3
16
  def make
@@ -0,0 +1,34 @@
1
+ # Example rake task to refresh your flv metadata using yamdi
2
+ # This assumes that you are using paperclip and have a Video
3
+ # model with an attachment of video.
4
+ # truncated example:
5
+ # class Video
6
+ # has_attached_file :video,
7
+ # :styles => {:orginal => {}},
8
+ # :processors => [:metadata_extractor]
9
+ # end
10
+ #
11
+ # The rake task below even works when using Amazon s3 for storage
12
+ # thanks to Paperclip.
13
+
14
+
15
+ namespace :video do
16
+ namespace :refresh do
17
+
18
+ desc "Regenerates metadata for uploaded flv videos."
19
+ task :metadata => :environment do
20
+ errors = []
21
+ # conditions assume default value of duration column has been set to 0
22
+ Video.find(:all, :conditions => ['duration = 0']).each do |video|
23
+ #ensure we are dealing with flv's
24
+ next unless video.video_file_name && video.video_file_name.include?('.flv')
25
+
26
+ result = video.video.reprocess!
27
+ errors << [video.id, video.errors] unless video.errors.blank?
28
+ result
29
+ end
30
+ errors.each{|e| puts "#{e.first}: #{e.last.full_messages.inspect}" }
31
+ end
32
+
33
+ end
34
+ end
@@ -2,8 +2,12 @@ require 'tempfile'
2
2
  require 'ostruct'
3
3
  require 'nokogiri'
4
4
 
5
+ require 'key_frame'
6
+
5
7
  class Yamdi
6
8
 
9
+ attr_accessor :metadata
10
+
7
11
  def initialize(flv_path)
8
12
  @metadata = Nokogiri.parse( parse(flv_path) )
9
13
  end
@@ -121,26 +125,7 @@ class Yamdi
121
125
  end
122
126
 
123
127
  def key_frames
124
- times_data_xml = @metadata.xpath("//keyframes/times/value")
125
- times = []
126
- times_data_xml.children.each do |el|
127
- times << el.inner_text.to_f
128
- end
129
-
130
- file_positions_xml = @metadata.xpath("//keyframes/filepositions/value")
131
- file_positions = []
132
- file_positions_xml.children.each do |el|
133
- file_positions << el.inner_text.to_i
134
- end
135
-
136
- count = 0
137
- key_frames = []
138
- while count < times.size do
139
- key_frames << OpenStruct.new(:time => times[count], :file_position => file_positions[count])
140
- count = count + 1
141
- end
142
-
143
- key_frames
128
+ KeyFrame.all_from_xml(@metadata.xpath("//keyframes"))
144
129
  end
145
130
 
146
131
  private
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "KeyFrame" do
4
+ let(:flv_path) { File.join(File.dirname(__FILE__), 'files', 'sample.flv') }
5
+
6
+ before(:all) do
7
+ @metadata_xml = Yamdi.new(flv_path).metadata
8
+ end
9
+
10
+ context "internal class methods" do
11
+ it "#self.get_times returns an array of times" do
12
+ times = KeyFrame.get_times(@metadata_xml.xpath("//keyframes/times/value"))
13
+ times.first.should eq(0.04)
14
+ times.last.should eq(6.04)
15
+ end
16
+
17
+ it "#self.get_file_positions returns an array of file positions" do
18
+ file_positions = KeyFrame.get_file_positions(@metadata_xml.xpath("//keyframes/filepositions/value"))
19
+ file_positions.first.should eq(1327)
20
+ file_positions.last.should eq(83017)
21
+ end
22
+ end
23
+
24
+ it "#self.all_from_xml returns an array of Key Frame objects" do
25
+ KeyFrame.all_from_xml(@metadata_xml.xpath("//keyframes")).class.should eq(Array)
26
+ end
27
+
28
+ before(:all) do
29
+ @key_frames = KeyFrame.all_from_xml(@metadata_xml.xpath("//keyframes"))
30
+ end
31
+
32
+ it "#time returns the proper time value" do
33
+ @key_frames.first.time.should eq(0.04)
34
+ @key_frames.last.time.should eq(6.04)
35
+ end
36
+
37
+ it "#file_position returns the proper file position value" do
38
+ @key_frames.first.file_position.should eq(1327)
39
+ @key_frames.last.file_position.should eq(83017)
40
+ end
41
+ end
@@ -116,26 +116,9 @@ describe "Yamdi" do
116
116
  @yamdi.last_key_frame_location.should eq(83017)
117
117
  end
118
118
 
119
- context "key frames" do
120
- before(:all) do
121
- @key_frame_1 = @yamdi.key_frames.first
122
- @key_frame_2 = @yamdi.key_frames.last
123
- end
124
-
125
- it "returns an array of key frame open structs" do
126
- @yamdi.key_frames.class.should eq(Array)
127
- @yamdi.key_frames.first.class.should eq(OpenStruct)
128
- @yamdi.key_frames.last.class.should eq(OpenStruct)
129
- end
130
-
131
- it "returns the proper time values" do
132
- @key_frame_1.time.should eq(0.04)
133
- @key_frame_2.time.should eq(6.04)
134
- end
135
-
136
- it "returns the proper file position values" do
137
- @key_frame_1.file_position.should eq(1327)
138
- @key_frame_2.file_position.should eq(83017)
139
- end
119
+ it "returns an array of key frames" do
120
+ @yamdi.key_frames.class.should eq(Array)
121
+ @yamdi.key_frames.first.class.should eq(KeyFrame)
122
+ @yamdi.key_frames.last.class.should eq(KeyFrame)
140
123
  end
141
124
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{yamdi}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bob Burbach"]
12
- s.date = %q{2011-01-25}
12
+ s.date = %q{2011-01-28}
13
13
  s.description = %q{Yamdi is a ruby wrapper around the command line tool yamdi (github.com/ioppermann/yamdi). You'll need yamdi installed in order for the gem to be of any use. If you are on OSX I recommend using homebrew (brew install yamdi).}
14
14
  s.email = %q{bob.burbach@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,9 +26,12 @@ Gem::Specification.new do |s|
26
26
  "README.rdoc",
27
27
  "Rakefile",
28
28
  "VERSION",
29
+ "lib/key_frame.rb",
29
30
  "lib/paperclip_processors/metadata_extractor.rb",
31
+ "lib/tasks/metadata_refresh.rake",
30
32
  "lib/yamdi.rb",
31
33
  "spec/files/sample.flv",
34
+ "spec/key_frame_spec.rb",
32
35
  "spec/spec_helper.rb",
33
36
  "spec/yamdi_spec.rb",
34
37
  "yamdi.gemspec"
@@ -39,6 +42,7 @@ Gem::Specification.new do |s|
39
42
  s.rubygems_version = %q{1.3.7}
40
43
  s.summary = %q{Yamdi is a ruby wrapper around the command line tool yamdi (github.com/ioppermann/yamdi).}
41
44
  s.test_files = [
45
+ "spec/key_frame_spec.rb",
42
46
  "spec/spec_helper.rb",
43
47
  "spec/yamdi_spec.rb"
44
48
  ]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yamdi
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bob Burbach
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-25 00:00:00 -08:00
18
+ date: 2011-01-28 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -131,9 +131,12 @@ files:
131
131
  - README.rdoc
132
132
  - Rakefile
133
133
  - VERSION
134
+ - lib/key_frame.rb
134
135
  - lib/paperclip_processors/metadata_extractor.rb
136
+ - lib/tasks/metadata_refresh.rake
135
137
  - lib/yamdi.rb
136
138
  - spec/files/sample.flv
139
+ - spec/key_frame_spec.rb
137
140
  - spec/spec_helper.rb
138
141
  - spec/yamdi_spec.rb
139
142
  - yamdi.gemspec
@@ -172,5 +175,6 @@ signing_key:
172
175
  specification_version: 3
173
176
  summary: Yamdi is a ruby wrapper around the command line tool yamdi (github.com/ioppermann/yamdi).
174
177
  test_files:
178
+ - spec/key_frame_spec.rb
175
179
  - spec/spec_helper.rb
176
180
  - spec/yamdi_spec.rb