yamdi 0.1.1 → 0.1.2

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.
@@ -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