awslive-poster 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 46d613313ddc2fe0727ddd7d848d4036ba12dfb127ce1f59cb4b28ab111fadc1
4
+ data.tar.gz: a03630438dd58e6250bdbdae95f91c58e4b6cf8344a270f249d2902008ee87b6
5
+ SHA512:
6
+ metadata.gz: b600f73b6936af7645dc67e9e9938fd9c6367316d5d10251485b44fca3962b1c6a26bb542336311620c0f1b3fd914a0d8a555129a39e92e7bc9ec36367b8365d
7
+ data.tar.gz: 5adc0432f41e2d0422352a5c73e07983cab835ed22e3e8b756c8a6e43e5c62cb43ca66309c89fdc3daea1b780e58712e17c7b5b528fe223b67f081dbb10708fc
@@ -0,0 +1 @@
1
+ require 'awslive-poster/awslive_poster'
@@ -0,0 +1,154 @@
1
+ require 'aws-sdk-medialive'
2
+ require 'aws-sdk-s3'
3
+ require 'uri'
4
+
5
+ module Awslive
6
+ class Poster
7
+
8
+ class InvalidChannelState < StandardError; end
9
+ class NoFrameCaptureOutputGroup < StandardError; end
10
+ class PosterImageDoesNotExist < StandardError; end
11
+ class NoStartTimeInTag < StandardError; end
12
+
13
+ MAX_CHANNEL_START_TIME = 2 * 60
14
+
15
+ def initialize(channel_id, access_key=nil , access_secret =nil, region = nil)
16
+ credentials = Aws::SharedCredentials.new
17
+ if !access_key.nil? && !access_secret.nil?
18
+ aws_region = 'us-east-1' if region.nil?
19
+ @medialiveclient = Aws::MediaLive::Client.new( :access_key_id => access_key, :secret_access_key => access_secret, :region => aws_region )
20
+ @s3 = Aws::S3::Resource.new( :access_key_id => access_key, :secret_access_key => access_secret, :region => aws_region )
21
+ elsif credentials.set?
22
+ @medialiveclient = Aws::MediaLive::Client.new(:credentials => credentials)
23
+ @s3 = Aws::S3::Resource.new(:credentials => credentials)
24
+ else
25
+ @medialiveclient = Aws::MediaLive::Client.new
26
+ @s3 = Aws::S3::Resource.new
27
+ end
28
+ @channel_id = channel_id
29
+ @last_computed_time = nil
30
+ @last_preview_url = nil
31
+ @interval = nil
32
+ end
33
+
34
+ def get_url(channel_info = nil)
35
+ if !@last_computed_time.nil? && !@last_preview_url.nil? && !@interval.nil?
36
+ threshold_gap = @interval > MAX_CHANNEL_START_TIME ? MAX_CHANNEL_START_TIME : @interval
37
+ current_time = Time.now.to_i
38
+ if current_time - @last_computed_time < threshold_gap
39
+ # quick fetch hence returning already computed preview URL.
40
+ puts "returning from cache"
41
+ return @last_preview_url
42
+ end
43
+ end
44
+ preview_url = nil
45
+ channel_info = @medialiveclient.describe_channel({ :channel_id => "#{@channel_id}" }) if channel_info.nil?
46
+ channel_state = channel_info[:state]
47
+ if channel_state == "RUNNING"
48
+ @last_computed_time = Time.now.to_i
49
+ out_group = get_framecapture_group(channel_info["encoder_settings"])
50
+ raise NoFrameCaptureOutputGroup.new("Framecapture output group should be configured!") if out_group.nil?
51
+ start_time = get_channel_start_time(channel_info)
52
+ raise NoStartTimeInTag.new("channel_start_time should be provisioned in Channel tag!") if start_time.nil?
53
+ dest_id = get_dest_info(out_group)
54
+ url = get_dest_url(dest_id, channel_info)
55
+ uri = URI(url)
56
+ modifier = get_framecapture_modifier(out_group)
57
+ @interval = get_framecapture_interval(out_group, channel_info)
58
+ seq_counter = compute_index(start_time, @interval)
59
+ suffix = uri.path[1..-1]
60
+ bucket = @s3.bucket("#{uri.host}")
61
+ obj = bucket.object("#{suffix}#{modifier}.#{seq_counter}.jpg")
62
+ if obj.exists?
63
+ preview_url = obj.presigned_url(:get)
64
+ else
65
+ raise PosterImageDoesNotExist.new("Poster Image #{suffix}#{modifier}.#{seq_counter}.jpg Does not exist!")
66
+ end
67
+ else
68
+ raise InvalidChannelState.new("Channel Need to be in running state!, current state is #{channel_state}")
69
+ end
70
+ @last_preview_url = preview_url
71
+ preview_url
72
+ end
73
+
74
+ def compute_index(start_time, interval)
75
+ channel_start_time = Time.iso8601(start_time).to_i
76
+ current_time = Time.now.utc.to_i
77
+ diff_time = current_time - channel_start_time
78
+ image_index = (diff_time / interval.to_i).to_i
79
+ index = image_index.to_s.rjust(5,'0')
80
+ index
81
+ end
82
+
83
+ def get_channel_start_time(channel_info)
84
+ start_time = channel_info.tags["channel_start_time"]
85
+ start_time
86
+ end
87
+
88
+ def get_framecapture_group(encode_setting)
89
+ out_grp = nil
90
+ outputgroups = encode_setting["output_groups"] rescue nil
91
+ unless outputgroups.nil?
92
+ outputgroups.each do | output |
93
+ if !output["output_group_settings"]["frame_capture_group_settings"].nil?
94
+ out_grp = output
95
+ break if !out_grp.nil?
96
+ end
97
+ end
98
+ end
99
+ out_grp
100
+ end
101
+
102
+ def get_dest_info(out_grp)
103
+ dest = nil
104
+ if !out_grp["output_group_settings"]["frame_capture_group_settings"].nil?
105
+ dest = out_grp["output_group_settings"]["frame_capture_group_settings"]["destination"]["destination_ref_id"] rescue nil
106
+ end
107
+ dest
108
+ end
109
+
110
+ def get_dest_url(dest_info, channel_info)
111
+ url = nil
112
+ if !channel_info["destinations"].nil?
113
+ channel_info["destinations"].each do | dest |
114
+ if dest["id"] == dest_info
115
+ url = dest["settings"][0]["url"]
116
+ break if !url.nil?
117
+ end
118
+ end
119
+ end
120
+ url
121
+ end
122
+
123
+ def get_framecapture_modifier(out_grp)
124
+ modifier = out_grp["outputs"][0]["output_settings"]["frame_capture_output_settings"]["name_modifier"] rescue nil
125
+ modifier
126
+ end
127
+
128
+ def get_framecapture_interval(out_grp, channel_info)
129
+ interval = nil
130
+ video_desc_name = out_grp["outputs"][0]["video_description_name"]
131
+ if !video_desc_name.nil?
132
+ video_desc_info = get_video_description_info(video_desc_name, channel_info)
133
+ if !video_desc_info.nil?
134
+ interval = video_desc_info["codec_settings"]["frame_capture_settings"]["capture_interval"]
135
+ end
136
+ end
137
+ interval
138
+ end
139
+
140
+ def get_video_description_info(desc_name, channel_info)
141
+ video_info = nil
142
+ videos_desc = channel_info["encoder_settings"]["video_descriptions"]
143
+ if !videos_desc.nil?
144
+ videos_desc.each do | description |
145
+ if description["name"] == desc_name
146
+ video_info = description
147
+ break
148
+ end
149
+ end
150
+ end
151
+ video_info
152
+ end
153
+ end
154
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awslive-poster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Maheshwaran G
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-medialive
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.40'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.40'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-sdk-s3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.40'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.40'
69
+ description: Utility that generates the Poster Image URL for the running AWS medialive
70
+ channel
71
+ email:
72
+ - maheshwarang@ooyala.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/awslive-poster.rb
78
+ - lib/awslive-poster/awslive_poster.rb
79
+ homepage: https://github.com/cloudaffair/awslive-poster
80
+ licenses:
81
+ - MIT
82
+ metadata:
83
+ homepage_uri: https://github.com/cloudaffair/awslive-poster
84
+ source_code_uri: https://github.com/cloudaffair/awslive-poster
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.1.2
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Utility that generates the Poster Image URL for the running AWS medialive
104
+ channel
105
+ test_files: []