video_converter 0.7.8 → 0.7.9

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.
@@ -14,6 +14,7 @@ require "video_converter/mp4frag"
14
14
  require "video_converter/object"
15
15
  require "video_converter/output"
16
16
  require "video_converter/version"
17
+ require "video_converter/openssl"
17
18
  require "video_screenshoter"
18
19
 
19
20
  module VideoConverter
@@ -58,10 +58,14 @@ module VideoConverter
58
58
  end
59
59
 
60
60
  def encrypt(options = {})
61
- outputs.each do |output|
62
- if output.drm == 'adobe'
61
+ outputs.each do |output|
62
+ case output.drm
63
+ when 'adobe'
63
64
  output.options.merge!(options)
64
65
  F4fpackager.run(output) or return false
66
+ when 'hls'
67
+ output.options.merge!(options)
68
+ OpenSSL.run(output) or return false
65
69
  end
66
70
  end
67
71
  true
@@ -58,7 +58,9 @@ module VideoConverter
58
58
  res = File.join(File.basename(output.chunks_dir), File.basename(chunk)) + "\n" + res
59
59
  res = "#EXTINF:%0.2f,\n" % duration + res
60
60
  end
61
- res = "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:#{durations.max.to_f.ceil}\n#EXT-X-MEDIA-SEQUENCE:0\n" + res + "#EXT-X-ENDLIST"
61
+ encryption_info = OpenSSL.get_encryption_key_path(output)
62
+ encryption_info = "#EXT-X-KEY:METHOD=AES-128,URI=\"#{encryption_info}\"\n" if encryption_info
63
+ res = "#EXTM3U\n#{encryption_info}#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:#{durations.max.to_f.ceil}\n#EXT-X-MEDIA-SEQUENCE:0\n" + res + "#EXT-X-ENDLIST"
62
64
  !!File.open(File.join(output.work_dir, output.filename), 'w') { |f| f.write res }
63
65
  end
64
66
 
@@ -0,0 +1,70 @@
1
+ module VideoConverter
2
+ class OpenSSL
3
+ class << self
4
+ attr_accessor :bin, :command, :encryption_type
5
+ end
6
+
7
+ #TODO locate openssl
8
+ self.bin = 'openssl'
9
+ self.encryption_type = 'aes-128-cbc'
10
+ self.command = '%{bin} %{encryption_type} -e -in %{chunk} -out %{encrypted_chunk} -nosalt -iv %{initialization_vector} -K %{encryption_key}'
11
+
12
+ def self.run(output)
13
+ success = true
14
+ encryption_dir = FileUtils.mkdir_p("#{output.chunks_dir}_encrypted").first
15
+ chunks = Dir::glob(File.join(output.chunks_dir, "#{LiveSegmenter.chunk_prefix}-*[0-9].ts")).sort do |c1, c2|
16
+ File.basename(c2).match(/\d+/).to_s.to_i <=> File.basename(c1).match(/\d+/).to_s.to_i
17
+ end
18
+ chunks.each_with_index do |chunk, index|
19
+ initialization_vector = "%032x" % index
20
+ success &&= Command.new(command, prepare_params( :chunk => chunk, :encrypted_chunk => File.join(encryption_dir,File.basename(chunk)),
21
+ :initialization_vector => initialization_vector, :encryption_key => OpenSSL.get_encryption_key(output) )).execute
22
+ end
23
+ remove_old_dir(output) if success
24
+ success
25
+ end
26
+
27
+ def self.get_encryption_key_path(output)
28
+ if output.encryption_key
29
+ File.open(File.join(output.work_dir,'video.key'), 'wb') { |f| f.puts output.encryption_key }
30
+ 'video.key'
31
+ elsif output.encryption_key_url
32
+ uri = URI(output.encryption_key_url)
33
+ File.open(File.join(output.work_dir,'url.video.key'), 'wb') { |f| f.puts Net::HTTP.get(uri.host, uri.path) }
34
+ output.encryption_key_url
35
+ else
36
+ nil
37
+ end
38
+ end
39
+
40
+ def self.get_encryption_key(output)
41
+ if output.encryption_key
42
+ File.join(output.work_dir, "video.key")
43
+ elsif output.encryption_key_url
44
+ File.join(output.work_dir, "url.video.key")
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def self.prepare_params(params)
53
+ {
54
+ :bin => bin,
55
+ :encryption_type => encryption_type,
56
+ :chunk => params[:chunk],
57
+ :encrypted_chunk => params[:encrypted_chunk],
58
+ :initialization_vector => params[:initialization_vector],
59
+ :encryption_key => `hexdump -e '16/1 "%02x"' #{params[:encryption_key]}`
60
+ }
61
+ end
62
+
63
+ def self.remove_old_dir(output)
64
+ FileUtils.rm_r(output.chunks_dir)
65
+ FileUtils.mv("#{output.chunks_dir}_encrypted", output.chunks_dir)
66
+ FileUtils.rm (File.join(output.work_dir,'url.video.key')) if File.exists?(File.join(output.work_dir,'url.video.key'))
67
+ end
68
+
69
+ end
70
+ end
@@ -9,7 +9,7 @@ module VideoConverter
9
9
  self.log = 'converter.log'
10
10
  self.keyframe_interval_in_seconds = 4
11
11
 
12
- attr_accessor :chunks_dir, :crop, :drm, :faststart, :ffmpeg_output, :filename, :group, :height, :log, :mkdir_mode, :no_fragments, :one_pass, :options, :path, :rotate, :streams, :thumbnails, :type, :uid, :volume, :watermarks, :width, :work_dir
12
+ attr_accessor :chunks_dir, :crop, :drm, :faststart, :ffmpeg_output, :filename, :group, :height, :log, :mkdir_mode, :no_fragments, :one_pass, :options, :path, :rotate, :streams, :thumbnails, :type, :uid, :volume, :watermarks, :width, :work_dir, :encryption_key, :encryption_key_url
13
13
 
14
14
  def initialize params = {}
15
15
  self.work_dir = File.join(self.class.work_dir, params[:uid])
@@ -35,7 +35,7 @@ module VideoConverter
35
35
  self.ffmpeg_output = File.join(work_dir, filename)
36
36
  end
37
37
  raise ArgumentError.new('Invalid type') unless %w(default segmented playlist).include?(type)
38
- [:path, :streams, :width, :height, :one_pass, :rotate, :faststart, :thumbnails, :group, :drm, :no_fragments, :crop, :watermarks, :volume].each { |attr| self.send("#{attr}=", params[attr]) }
38
+ [:path, :streams, :width, :height, :one_pass, :rotate, :faststart, :thumbnails, :group, :drm, :no_fragments, :crop, :watermarks, :volume, :encryption_key, :encryption_key_url].each { |attr| self.send("#{attr}=", params[attr]) }
39
39
  [:video_bitrate, :audio_bitrate].each { |bitrate| params[bitrate] = "#{params[bitrate]}k" if params[bitrate].is_a?(Numeric) }
40
40
 
41
41
  # options will be substituted to convertation commands
@@ -1,3 +1,3 @@
1
1
  module VideoConverter
2
- VERSION = "0.7.8"
2
+ VERSION = "0.7.9"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: video_converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-19 00:00:00.000000000 Z
12
+ date: 2014-10-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: video_screenshoter
@@ -117,6 +117,7 @@ files:
117
117
  - lib/video_converter/live_segmenter.rb
118
118
  - lib/video_converter/mp4frag.rb
119
119
  - lib/video_converter/object.rb
120
+ - lib/video_converter/openssl.rb
120
121
  - lib/video_converter/output.rb
121
122
  - lib/video_converter/version.rb
122
123
  - test/fixtures/chunk0.ts
@@ -141,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
142
  version: '0'
142
143
  segments:
143
144
  - 0
144
- hash: 2912131658363711804
145
+ hash: 646644403417642151
145
146
  required_rubygems_version: !ruby/object:Gem::Requirement
146
147
  none: false
147
148
  requirements:
@@ -150,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
151
  version: '0'
151
152
  segments:
152
153
  - 0
153
- hash: 2912131658363711804
154
+ hash: 646644403417642151
154
155
  requirements:
155
156
  - ffmpeg, version 1.2 or greated configured with libx264 and libfaac
156
157
  - live_segmenter to convert to hls