samvera_hls 0.3.7 → 0.4.4
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.
- checksums.yaml +4 -4
- data/app/controllers/concerns/samvera_hls/file_sets_controller_behavior.rb +6 -8
- data/app/models/concerns/samvera_hls/file_set_behavior.rb +24 -121
- data/app/services/samvera_hls/hls_output_file_service.rb +1 -1
- data/app/services/samvera_hls/hls_playlist_generator.rb +125 -0
- data/lib/samvera_hls/version.rb +1 -1
- metadata +7 -7
- data/app/models/concerns/samvera_hls/solr_document_behavior.rb +0 -112
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fabf475ee9c330289d588739a782d74302ea15aeb48d5e1be604dd096afab002
         | 
| 4 | 
            +
              data.tar.gz: 32c5e0a93ad559431881f6b3855e66c21848acf5fce558a05f12fbd50436b1a5
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 | 
            -
                   | 
| 13 | 
            -
                  @ | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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( | 
| 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  | 
| 9 | 
            -
                   | 
| 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  | 
| 46 | 
            -
                   | 
| 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  | 
| 65 | 
            -
                   | 
| 66 | 
            -
             | 
| 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 | 
            -
                     | 
| 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  | 
| 85 | 
            -
                   | 
| 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  | 
| 96 | 
            -
             | 
| 34 | 
            +
                def video_mime_types
         | 
| 35 | 
            +
                  self.class.video_mime_types
         | 
| 97 36 | 
             
                end
         | 
| 98 37 |  | 
| 99 | 
            -
                def  | 
| 38 | 
            +
                def create_hls_audio_derivatives filename
         | 
| 100 39 | 
             
                  outputs = [
         | 
| 101 | 
            -
                    { label: ' | 
| 102 | 
            -
                    { label: ' | 
| 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  | 
| 109 | 
            -
                  outputs = [{ label: :thumbnail, format: 'jpg', url: derivative_url('thumbnail') },
         | 
| 110 | 
            -
             | 
| 111 | 
            -
                             { label: ' | 
| 112 | 
            -
                             { label: ' | 
| 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[: | 
| 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
         | 
    
        data/lib/samvera_hls/version.rb
    CHANGED
    
    
    
        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. | 
| 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:  | 
| 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. | 
| 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
         |