samvera_hls 0.3.7 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f32eacb28341f9d899a5480d319e4a81932a98b3e127b16527df4a35ccaf341b
4
- data.tar.gz: 739fecf309e110cdc1a8afa89da970dfbb8bb4f6e1a0ca07e293da377de11526
3
+ metadata.gz: fabf475ee9c330289d588739a782d74302ea15aeb48d5e1be604dd096afab002
4
+ data.tar.gz: 32c5e0a93ad559431881f6b3855e66c21848acf5fce558a05f12fbd50436b1a5
5
5
  SHA512:
6
- metadata.gz: 9c40564b3b77a51618ecab582b5410d5428091ab4679bef4c6f1ea5555691bd9f4f8f94af7335ed5c8e11809edf44a06564977e7f03a74354c7199b66b1064d6
7
- data.tar.gz: 944f49e17331dc7559d629620f89bd3ead7105a6c94ca153ffb8d012467ff007762e2d3f9aee750ab155730ab5f60463b0b91d3b431e325697dd33be5b993c0d
6
+ metadata.gz: 90961c9d137aa7e2f62bd434e55070e04fed71f733a4439905c151e97a4b402d8817d1a7ea239e87c997021a0e812a740afe9e90ff9f4585f4d5945ba63f5832
7
+ data.tar.gz: 2dcc42a69be39cb831d1f2832a46021f29f7c046d0d793f8d48d9895fedbdc70d3af4a60fd80a1152b149d2290e5cde3c6c021b7f6f951e767fd63446359d1fb
@@ -9,23 +9,21 @@ module SamveraHls
9
9
 
10
10
  def embed
11
11
  response.headers["X-FRAME-OPTIONS"] = "ALLOWALL"
12
- fs = FileSet.find(params[:id])
13
- @playlist_url = fs.hls_master_url
14
- @media_partial = media_display_partial(fs)
12
+ @playlist_url = File.join("file_set",params[:id],"hls.m3u8")
13
+ @media_partial = media_display_partial(params[:id])
15
14
  render layout: false
16
15
  end
17
16
 
18
17
  def master
19
- fs = FileSet.find(params[:id])
20
- render inline: fs.hls_master_playlist(root_url), content_type: 'application/x-mpegurl'
18
+ render inline: SamveraHls::HlsPlaylistGenerator.hls_master_playlist(params[:id],root_url), content_type: 'application/x-mpegurl'
21
19
  end
22
20
 
23
21
  def variant
24
- fs = FileSet.find(params[:id])
25
- render inline: fs.hls_segment_playlist(root_url,params[:format]), content_type: 'application/x-mpegurl'
22
+ render inline: SamveraHls::HlsPlaylistGenerator.hls_segment_playlist(params[:id],root_url,params[:format]), content_type: 'application/x-mpegurl'
26
23
  end
27
24
 
28
- def media_display_partial(file_set)
25
+ def media_display_partial(file_set_id)
26
+ file_set = SolrDocument.find(file_set_id)
29
27
  base = 'file_sets/media_display'
30
28
  if file_set.image?
31
29
  File.join('hyrax',base,'image')
@@ -1,151 +1,54 @@
1
1
  require "samvera_hls/derivatives/video_derivatives"
2
2
  require "samvera_hls/derivatives/audio_derivatives"
3
+ require "uri"
3
4
 
4
5
  module SamveraHls
5
6
  module FileSetBehavior
6
7
  extend ActiveSupport::Concern
7
8
 
8
- def create_hls_derivatives(filename)
9
- case mime_type
10
- when *self.class.audio_mime_types
11
- hls_dir = File.join(derivative_dir,"hls")
12
- create_audio_derivates filename, hls_dir
13
- when *self.class.video_mime_types
14
- hls_dir = File.join(derivative_dir,"hls")
15
- create_video_derivates filename, hls_dir
16
- else
17
- return false
18
- end
19
- end
20
-
21
- def hls_master_url
22
- File.join("file_set",id,"hls.m3u8")
23
- end
24
-
25
- def hls_master_playlist root_url
26
- root_url = root_url.gsub("/?locale=en","")
27
- type = mime_type.split('/')[0]
28
- defaults = hls_config[type]["default"]
29
- playlist = "#EXTM3U\n"
30
- playlist << "#EXT-X-VERSION:6\n"
31
- variants.each{|variant|
32
- next if variant.blank?
33
- path, filename = File.split(variant)
34
- format = filename.gsub(".m3u8","")
35
- options = defaults.merge(hls_config[type][format])
36
- playlist << "#EXT-X-STREAM-INF:PROGRAM-ID=1,"
37
- playlist << "BANDWIDTH=#{options["maxrate"]},"
38
- playlist << "CODECS=\"#{options["codec_code"]}\","
39
- playlist << "RESOLUTION=#{options["resolution"]}\n"
40
- playlist << File.join(root_url,variant_url(format)) + "\n"
41
- }
42
- playlist
9
+ def self.audio_mime_types
10
+ ['audio/mp3', 'audio/mpeg', 'audio/wav', 'audio/x-wave', 'audio/x-wav', 'audio/ogg', 'audio/flac','audio/x-flac', 'audio/x-aiff', 'audio/aiff', ]
43
11
  end
44
12
 
45
- def hls_segment_playlist root_url, format
46
- root_url = root_url.gsub("/?locale=en","")
47
- playlist = ""
48
- File.open(segment_playlist_path(format),'r') {|file|
49
- file.each_line do |line|
50
- if line.include? ".ts" then
51
- playlist << File.join(root_url,
52
- segment_url_base,
53
- timestamp.to_s,
54
- token(line),
55
- line).strip+"\n"
56
- else
57
- playlist << line.strip+"\n"
58
- end
59
- end
60
- }
61
- playlist
13
+ def self.video_mime_types
14
+ ['video/mp4']
62
15
  end
63
16
 
64
- def derivative_url(destination_name = nil)
65
- if destination_name.nil?
66
- @deriv_url ||= derivative_dir.gsub(Hyrax.config.derivatives_path,"")
17
+ def create_hls_derivatives(filename)
18
+ case mime_type
19
+ when *audio_mime_types
20
+ create_hls_audio_derivatives filename
21
+ when *video_mime_types
22
+ create_hls_video_derivatives filename
67
23
  else
68
- path = derivative_path(destination_name)
69
- URI("file://#{path}").to_s
70
- end
71
- end
72
-
73
- module ClassMethods
74
-
75
- def audio_mime_types
76
- # audio/x-wave is the mime type that fits 0.6.0 returns for a wav file.
77
- # audio/mpeg is the mime type that fits 0.6.0 returns for an mp3 file.
78
- ['audio/mp3', 'audio/mpeg', 'audio/wav', 'audio/x-wave', 'audio/x-wav', 'audio/ogg', 'audio/flac','audio/x-flac', 'audio/x-aiff', 'audio/aiff', ]
24
+ return false
79
25
  end
80
26
  end
81
27
 
82
28
  private
83
29
 
84
- def segment_url_base
85
- File.join("stream",derivative_url,"hls")
86
- end
87
-
88
- def variants
89
- variants = Dir.glob(File.join(derivative_dir,"hls","*.m3u8"))
90
- variants.map!{ |file|
91
- name = File.split(file)[1]
92
- }
30
+ def audio_mime_types
31
+ self.class.audio_mime_types
93
32
  end
94
33
 
95
- def variant_url format
96
- File.join("file_set",id,format,"variant.m3u8")
34
+ def video_mime_types
35
+ self.class.video_mime_types
97
36
  end
98
37
 
99
- def create_audio_derivates filename, hls_dir
38
+ def create_hls_audio_derivatives filename
100
39
  outputs = [
101
- { label: 'mp3', format: 'mp3', url: derivative_url('mp3') },
102
- { label: 'ogg', format: 'ogg', url: derivative_url('ogg') },
103
- { label: 'hls_hd', format: 'hls_hd',path: hls_dir},
104
- { label: 'hls', format: 'hls', path: hls_dir}]
40
+ { label: 'hls_hd', format: 'hls_hd', id: id},
41
+ { label: 'hls', format: 'hls', id: id}]
105
42
  SamveraHls::Derivatives::AudioDerivatives.create(filename,{:outputs => outputs})
106
43
  end
107
44
 
108
- def create_video_derivates filename, hls_dir
109
- outputs = [{ label: :thumbnail, format: 'jpg', url: derivative_url('thumbnail') },
110
- # { label: 'webm', format: 'webm', url: derivative_url('webm') },
111
- { label: 'mp4', format: 'mp4', url: derivative_url('mp4') },
112
- { label: 'hls_high', format: "hls_high", path: hls_dir},
113
- { label: 'hls_med', format: "hls_med", path: hls_dir},
114
- { label: 'hls_low', format: "hls_low", path: hls_dir}]
45
+ def create_hls_video_derivatives filename
46
+ outputs = [{ label: :thumbnail, format: 'jpg', url: SamveraHls::HlsPlaylistGenerator.derivative_url(id,'thumbnail') },
47
+ { label: 'hls_high', format: "hls_high", id: id },
48
+ { label: 'hls_med', format: "hls_med", id: id },
49
+ { label: 'hls_low', format: "hls_low", id: id }]
115
50
  SamveraHls::Derivatives::VideoDerivatives.create(filename,{:outputs => outputs})
116
51
  end
117
52
 
118
- def token line
119
- @token ||= Digest::SHA256.hexdigest("/" + File.join(segment_url_base,timestamp.to_s,line).strip[0...-9] + token_secret)
120
- end
121
-
122
- def timestamp
123
- @timestamp ||= Time.now.to_i + 7200
124
- end
125
-
126
- def token_secret
127
- @token_secret ||= ENV['hls_token_secret']
128
- end
129
-
130
- def hls_config
131
- @hls_config ||= YAML.load_file(Rails.root.join('config','hls.yml'))
132
- end
133
-
134
- def segment_playlist_path format
135
- File.join(derivative_dir,"hls",format+".m3u8")
136
- end
137
-
138
- def derivative_dir
139
- File.split(derivative_path("dummy"))[0]
140
- end
141
-
142
- def derivative_path destination_name
143
- derivative_path_service.derivative_path_for_reference(self, destination_name)
144
- end
145
-
146
- def derivative_path_service
147
- Hyrax::DerivativePath
148
- end
149
-
150
53
  end
151
54
  end
@@ -2,7 +2,7 @@ require 'hydra/derivatives'
2
2
  module SamveraHls
3
3
  class HlsOutputFileService < Hyrax::PersistDerivatives
4
4
  def self.call( directives,temp_dir)
5
- hls_dir = directives[:path]
5
+ hls_dir = SamveraHls::HlsPlaylistGenerator.hls_dir(directives[:id])
6
6
  FileUtils.mkdir_p(hls_dir)
7
7
  FileUtils.move(Dir.glob(temp_dir+"/*") , hls_dir)
8
8
  end
@@ -0,0 +1,125 @@
1
+ module SamveraHls
2
+ class HlsPlaylistGenerator
3
+ class <<self
4
+
5
+ def hls_master_url file_set_id
6
+ File.join("file_set",file_set_id,"hls.m3u8")
7
+ end
8
+
9
+ def hls_master_playlist file_set_id, root_url
10
+ # make sure the root url doesn't get any default params attached (e.g. locale)
11
+ parsed_url = URI::parse(root_url)
12
+ parsed_url.fragment = parsed_url.query = nil
13
+ root_url = parsed_url.to_s
14
+
15
+ type = SolrDocument.find(file_set_id).mime_type.split('/')[0]
16
+ config = hls_config[type]
17
+ return nil if config.nil?
18
+ defaults = config["default"]
19
+ playlist = "#EXTM3U\n"
20
+ playlist << "#EXT-X-VERSION:6\n"
21
+ variants(file_set_id).each do |variant|
22
+ next if variant.blank?
23
+ path, filename = File.split(variant)
24
+ format = filename.gsub(".m3u8","")
25
+ options = defaults.merge(config[format])
26
+ playlist << "#EXT-X-STREAM-INF:PROGRAM-ID=1,"
27
+ playlist << "BANDWIDTH=#{options["maxrate"]},"
28
+ playlist << "CODECS=\"#{options["codec_code"]}\","
29
+ playlist << "RESOLUTION=#{options["resolution"]}\n"
30
+ playlist << File.join(root_url,variant_url(file_set_id,format)) + "\n"
31
+ end
32
+ playlist
33
+ end
34
+
35
+ def hls_segment_playlist file_set_id, root_url, format
36
+ # make sure the root url doesn't get any default params attached (e.g. locale)
37
+ parsed_url = URI::parse(root_url)
38
+ parsed_url.fragment = parsed_url.query = nil
39
+ root_url = parsed_url.to_s
40
+
41
+ # initialize timestamp once for whole playlist
42
+ timestamp = Time.now.to_i + 7200
43
+
44
+ playlist = ""
45
+
46
+ File.open(segment_playlist_path(file_set_id, format),'r') {|file|
47
+
48
+ variant_token = false;
49
+ file.each_line do |line|
50
+ if line.include? ".ts" then
51
+ # We only need to set the token once for each variant file.
52
+ # It doesn't depend on which segment we're playing, so we
53
+ # speed things up by only calculating one.
54
+ variant_token ||= token(file_set_id,line, timestamp)
55
+ if Rails.env == "development" || Rails.env == "test"
56
+ playlist << File.join(root_url,
57
+ segment_url_base(file_set_id),
58
+ line).strip+"\n"
59
+ else
60
+ playlist << File.join(root_url,
61
+ segment_url_base(file_set_id),
62
+ timestamp.to_s,
63
+ variant_token,
64
+ line).strip+"\n"
65
+ end
66
+ else
67
+ playlist << line.strip+"\n"
68
+ end
69
+ end
70
+ }
71
+ playlist
72
+ end
73
+
74
+ def hls_dir file_set_id
75
+ derivative_path(file_set_id,"hls").gsub(/\.hls\z/,"")
76
+ end
77
+
78
+ def derivative_url file_set_id, destination_name
79
+ derivative_path(file_set_id, destination_name).gsub(Hyrax.config.derivatives_path,"")
80
+ end
81
+
82
+ private
83
+
84
+ def token_secret
85
+ @token_secret ||= ENV['hls_token_secret']
86
+ end
87
+
88
+ def segment_url_base id
89
+ File.join("stream",derivative_url(id, "hls")).gsub(/\.hls\z/,"")
90
+ end
91
+
92
+ def token id, line, timestamp
93
+ Digest::SHA256.hexdigest("/" + File.join(segment_url_base(id),timestamp.to_s,line).strip[0...-9] + token_secret)
94
+ end
95
+
96
+ def segment_playlist_path id, format
97
+ File.join(hls_dir(id),"#{format}.m3u8")
98
+ end
99
+
100
+ def hls_config
101
+ @hls_config ||= YAML.load_file(Rails.root.join('config','hls.yml'))
102
+ end
103
+
104
+ def variants id
105
+ variants = Dir.glob(File.join(hls_dir(id),"*.m3u8"))
106
+ variants.map!{ |file|
107
+ name = File.split(file)[1]
108
+ }
109
+ end
110
+
111
+ def variant_url id, format
112
+ File.join("file_set",id,format,"variant.m3u8")
113
+ end
114
+
115
+ def derivative_path id, destination_name
116
+ derivative_path_service.derivative_path_for_reference(id, destination_name)
117
+ end
118
+
119
+ def derivative_path_service
120
+ Hyrax::DerivativePath
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -1,3 +1,3 @@
1
1
  module SamveraHls
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: samvera_hls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ned Henry, UCSC Library Digital Initiatives
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-29 00:00:00.000000000 Z
11
+ date: 2021-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -45,8 +45,8 @@ files:
45
45
  - app/assets/stylesheets/samvera-hls-styles.scss
46
46
  - app/controllers/concerns/samvera_hls/file_sets_controller_behavior.rb
47
47
  - app/models/concerns/samvera_hls/file_set_behavior.rb
48
- - app/models/concerns/samvera_hls/solr_document_behavior.rb
49
48
  - app/services/samvera_hls/hls_output_file_service.rb
49
+ - app/services/samvera_hls/hls_playlist_generator.rb
50
50
  - app/views/_playlist.html.erb
51
51
  - app/views/file_sets/embed.html.erb
52
52
  - app/views/file_sets/media_display/_audio_hls.html.erb
@@ -152,7 +152,7 @@ homepage: http://github.com/UCSCLibrary/samvera_hls
152
152
  licenses:
153
153
  - Apache License, v2.0
154
154
  metadata: {}
155
- post_install_message:
155
+ post_install_message:
156
156
  rdoc_options: []
157
157
  require_paths:
158
158
  - lib
@@ -167,8 +167,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
167
  - !ruby/object:Gem::Version
168
168
  version: '0'
169
169
  requirements: []
170
- rubygems_version: 3.0.3
171
- signing_key:
170
+ rubygems_version: 3.1.2
171
+ signing_key:
172
172
  specification_version: 4
173
173
  summary: An engine to add hls adaptive streaming to a samvera based application.
174
174
  test_files:
@@ -1,112 +0,0 @@
1
- module SamveraHls
2
- module SolrDocumentBehavior
3
- extend ActiveSupport::Concern
4
-
5
-
6
- def hls_master_url
7
- File.join("file_set",id,"hls.m3u8")
8
- end
9
-
10
- def hls_master_playlist root_url
11
- root_url = root_url.gsub("/?locale=en","")
12
- type = mime_type.split('/')[0]
13
- defaults = hls_config[type]["default"]
14
- playlist = "#EXTM3U\n"
15
- playlist << "#EXT-X-VERSION:6\n"
16
- variants.each{|variant|
17
- next if variant.blank?
18
- path, filename = File.split(variant)
19
- format = filename.gsub(".m3u8","")
20
- options = defaults.merge(hls_config[type][format])
21
- playlist << "#EXT-X-STREAM-INF:PROGRAM-ID=1,"
22
- playlist << "BANDWIDTH=#{options["maxrate"]},"
23
- playlist << "CODECS=\"#{options["codec_code"]}\","
24
- playlist << "RESOLUTION=#{options["resolution"]}\n"
25
- playlist << File.join(root_url,variant_url(format)) + "\n"
26
- }
27
- playlist
28
- end
29
-
30
- def hls_segment_playlist root_url, format
31
- root_url = root_url.gsub("/?locale=en","")
32
- playlist = ""
33
- File.open(segment_playlist_path(format),'r') {|file|
34
- file.each_line do |line|
35
- if ENV["RAILS_ENV"] == 'development'
36
- this_segment_url = File.join(root_url,
37
- segment_url_base,
38
- line).strip
39
- else
40
- this_segment_url = File.join(root_url,
41
- segment_url_base,
42
- timestamp.to_s,
43
- token(line),
44
- line).strip
45
- end
46
- if line.include? ".ts" then
47
- playlist << this_segment_url + "\n"
48
- else
49
- playlist << line.strip+"\n"
50
- end
51
- end
52
- }
53
- playlist
54
- end
55
-
56
-
57
- private
58
-
59
- def segment_url_base
60
- File.join("stream",derivative_url,"hls")
61
- end
62
-
63
- def variants
64
- variants = Dir.glob(File.join(derivative_dir,"hls","*.m3u8"))
65
- variants.map!{ |file|
66
- name = File.split(file)[1]
67
- }
68
- end
69
-
70
- def variant_url format
71
- File.join("file_set",id,format,"variant.m3u8")
72
- end
73
-
74
-
75
- def token line
76
- @token ||= Digest::SHA256.hexdigest("/" + File.join(segment_url_base,timestamp.to_s,line).strip[0...-9] + token_secret)
77
- end
78
-
79
- def timestamp
80
- @timestamp ||= Time.now.to_i + 7200
81
- end
82
-
83
- def token_secret
84
- if ENV["RAILS_ENV"] == 'development'
85
- return ''
86
- else
87
- return @token_secret ||= ENV['hls_token_secret']
88
- end
89
- end
90
-
91
- def hls_config
92
- @hls_config ||= YAML.load_file(Rails.root.join('config','hls.yml'))
93
- end
94
-
95
- def segment_playlist_path format
96
- File.join(derivative_dir,"hls",format+".m3u8")
97
- end
98
-
99
- def derivative_dir
100
- File.split(derivative_path("dummy"))[0]
101
- end
102
-
103
- def derivative_path destination_name
104
- derivative_path_service.derivative_path_for_reference(self, destination_name)
105
- end
106
-
107
- def derivative_path_service
108
- Hyrax::DerivativePath
109
- end
110
-
111
- end
112
- end