pili 1.3.1 → 1.5.0

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,181 @@
1
+ require 'pili'
2
+
3
+ # Replace with your keys here
4
+ ACCESS_KEY = 'Qiniu_AccessKey'
5
+ SECRETE_KEY = 'Qiniu_SecretKey'
6
+
7
+ # Replace with your hub name
8
+ HUB_NAME = 'Pili_Hub_Name' # The Hub must be exists before use
9
+
10
+ # Change API host as necessary
11
+ # pili.qiniuapi.com as deafult
12
+ # pili-lte.qiniuapi.com is the latest RC version
13
+ Pili::Config.init api_host: 'pili-lte.qiniuapi.com'
14
+
15
+
16
+ # Instantiate an Pili hub
17
+ credentials = Pili::Credentials.new(ACCESS_KEY, SECRETE_KEY)
18
+ hub = Pili::Hub.new(credentials, HUB_NAME)
19
+ puts "Hub initialize =>\n#{hub.inspect}\n\n"
20
+
21
+
22
+ # hub
23
+
24
+ # Create a new Stream
25
+ begin
26
+ title = nil # optional, default is auto-generated
27
+ publish_key = nil # optional, a secret key for signing the <publishToken>
28
+ publish_security = nil # optional, can be "dynamic" or "static", default is "dynamic"
29
+
30
+ # stream = hub.create_stream()
31
+ # or
32
+ stream = hub.create_stream(title: title, publish_key: publish_key, publish_security: publish_security)
33
+ puts "Hub create_stream() =>\n#{stream.inspect}\n\n"
34
+ rescue Exception => e
35
+ puts "Hub create_stream() failed. Caught exception:\n#{e.http_body}\n\n"
36
+ end
37
+
38
+
39
+ # Get a Stream
40
+ begin
41
+ stream = hub.get_stream(stream.id)
42
+ puts "Hub get_stream() =>\n#{stream.inspect}\n\n"
43
+ rescue Exception => e
44
+ puts "Hub get_stream() failed. Caught exception:\n#{e.http_body}\n\n"
45
+ end
46
+
47
+
48
+ # List streams
49
+ begin
50
+ marker = nil # optional
51
+ limit = nil # optional
52
+ title = nil # optional
53
+ streams = hub.list_streams(marker: marker, limit: limit, title: title)
54
+ puts "Hub list_streams() =>\n#{streams.inspect}\n\n"
55
+ rescue Exception => e
56
+ puts "Hub list_streams() failed. Caught exception:\n#{e.http_body}\n\n"
57
+ end
58
+
59
+
60
+ # Stream
61
+
62
+ # To JSON String
63
+ json_string = stream.to_json()
64
+ puts "Stream stream.to_json() =>\n#{json_string}\n\n"
65
+
66
+
67
+ # Update a Stream
68
+ begin
69
+ publish_key = "new_secret_words" # optional, a secret key for signing the <publishToken>
70
+ publish_security = "static" # optional, can be "dynamic" or "static", default is "dynamic"
71
+ disabled = nil # optional, can be true or false
72
+ stream = stream.update(publish_key: publish_key, publish_security: publish_security, disabled: disabled)
73
+ puts "Stream update() =>\n#{stream.inspect}\n\n"
74
+ rescue Exception => e
75
+ puts "Stream update() failed. Caught exception:\n#{e.http_body}\n\n"
76
+ end
77
+
78
+
79
+ # Disable a Stream
80
+ begin
81
+ stream = stream.disable()
82
+ puts "Stream disable() =>\n#{stream.inspect}\n\n"
83
+ rescue Exception => e
84
+ puts "Stream disable() failed. Caught exception:\n#{e.http_body}\n\n"
85
+ end
86
+
87
+
88
+ # Enable a Stream
89
+ begin
90
+ stream = stream.enable()
91
+ puts "Stream enable() =>\n#{stream.inspect}\n\n"
92
+ rescue Exception => e
93
+ puts "Stream enable() failed. Caught exception:\n#{e.http_body}\n\n"
94
+ end
95
+
96
+
97
+ # Get stream status
98
+ begin
99
+ status_info = stream.status()
100
+ puts "Stream status() =>\n#{status_info.inspect}\n\n"
101
+ rescue Exception => e
102
+ puts "Stream status() failed. Caught exception:\n#{e.http_body}\n\n"
103
+ end
104
+
105
+
106
+ # Generate RTMP publish URL
107
+ publish_url = stream.rtmp_publish_url()
108
+ puts "Stream rtmp_publish_url() =>\n#{publish_url}\n\n"
109
+
110
+
111
+ # Generate RTMP live play URLs
112
+ urls = stream.rtmp_live_urls()
113
+ puts "Stream rtmp_live_urls() =>\n#{urls.inspect}\n\n"
114
+
115
+
116
+ # Generate HLS live play URLs
117
+ urls = stream.hls_live_urls()
118
+ puts "Stream hls_live_urls() =>\n#{urls.inspect}\n\n"
119
+
120
+
121
+ # Generate HTTP-FLV live play URLs
122
+ urls = stream.http_flv_live_urls()
123
+ puts "Stream http_flv_live_urls() =>\n#{urls.inspect}\n\n"
124
+
125
+
126
+ # Get stream segments
127
+ begin
128
+ start_time = nil # optional, integer, in second, unix timestamp
129
+ end_time = nil # optional, integer, in second, unix timestamp
130
+ limit = nil # optional, uint
131
+ segments = stream.segments(start_time: start_time, end_time: end_time, limit: limit)
132
+ puts "Stream segments() =>\n#{segments.inspect}\n\n"
133
+ rescue Exception => e
134
+ puts "Stream segments() failed. Caught exception:\n#{e.http_body}\n\n"
135
+ end
136
+
137
+
138
+ # Generate HLS playback URLs
139
+ start_time = 1440196065 # required, integer, in second, unix timestamp
140
+ end_time = 1440196105 # required, integer, in second, unix timestamp
141
+ urls = stream.hls_playback_urls(start_time, end_time)
142
+ puts "Stream hls_playback_urls() =>\n#{urls.inspect}\n\n"
143
+
144
+
145
+
146
+ # Snapshot
147
+ begin
148
+ name = "imageName.jpg" # required, string
149
+ format = "jpg" # required, string
150
+ options = {
151
+ :time => 1440067100, # optional, int64, in second, unix timestamp
152
+ :notify_url => nil # optional
153
+ }
154
+ result = stream.snapshot(name, format, options)
155
+ puts "Stream snapshot() =>\n#{result.inspect}\n\n"
156
+ rescue Exception => e
157
+ puts "Stream snapshot() failed. Caught exception:\n#{e.http_body}\n\n"
158
+ end
159
+
160
+
161
+ # Save Stream as
162
+ begin
163
+ name = "videoName.mp4" # required, string
164
+ format = "mp4" # required, string
165
+ start_time = 1440067100 # required, int64, in second, unix timestamp
166
+ end_time = 1440068104 # required, int64, in second, unix timestamp
167
+ notify_url = nil # optional
168
+ result = stream.save_as(name, format, start_time, end_time, notify_url)
169
+ puts "Stream save_as() =>\n#{result.inspect}\n\n"
170
+ rescue Exception => e
171
+ puts "Stream save_as() failed. Caught exception:\n#{e.http_body}\n\n"
172
+ end
173
+
174
+
175
+ # Delete a stream
176
+ begin
177
+ result = stream.delete()
178
+ puts "Stream delete() =>\n#{result.inspect}\n\n"
179
+ rescue Exception => e
180
+ puts "Stream delete() failed. Caught exception:\n#{e.http_body}\n\n"
181
+ end
data/lib/pili/api.rb CHANGED
@@ -5,70 +5,115 @@ module Pili
5
5
  module API
6
6
  class << self
7
7
 
8
- def get(access_key, secret_key, url)
9
- signature_options = {
10
- :url => url,
11
- :method => "GET"
8
+ def create_stream(credentials, hub_name, options = {})
9
+ url = "/streams"
10
+
11
+ body = {
12
+ :hub => hub_name,
13
+ :title => options[:title],
14
+ :publishKey => options[:publish_key],
15
+ :publishSecurity => options[:publish_security] == "static" ? "static" : "dynamic",
16
+ :clientIp => options[:client_ip]
12
17
  }
13
18
 
14
- encoded_sign = Auth.sign(secret_key, Auth.generate_signature(signature_options))
19
+ body.delete_if { |k, v| v.nil? }
15
20
 
16
- headers = { "Authorization" => "Qiniu #{access_key}:#{encoded_sign}" }
21
+ Stream.new credentials, RPC.post(credentials, url, body)
22
+ end
23
+
24
+
25
+ def get_stream(credentials, stream_id)
26
+ url = "/streams/" + stream_id
27
+ Stream.new credentials, RPC.get(credentials, url)
28
+ end
17
29
 
18
- response = HTTParty.get(url, :headers => headers)
19
30
 
20
- if response.code == 200
21
- response.parsed_response
22
- else
23
- raise ResponseError.new("Pili API Request Error", response)
31
+ def list_streams(credentials, hub_name, options = {})
32
+ url = "/streams?hub=#{hub_name}"
33
+
34
+ url += "&marker=#{options[:marker]}" unless Utils.blank?(options[:marker])
35
+ url += "&limit=#{options[:limit]}" if options[:limit].is_a?(Fixnum)
36
+ url += "&title=#{options[:title]}" unless Utils.blank?(options[:title])
37
+
38
+ streams = []
39
+
40
+ RPC.get(credentials, url)["items"].each do |item|
41
+ streams << Stream.new(credentials, item)
24
42
  end
43
+
44
+ streams
25
45
  end
26
46
 
27
47
 
28
- def post(access_key, secret_key, url, body)
29
- signature_options = {
30
- :url => url,
31
- :content_type => "application/json",
32
- :method => "POST",
33
- :body => body
34
- }
48
+ def get_stream_status(credentials, stream_id)
49
+ url = "/streams/#{stream_id}/status"
50
+ RPC.get(credentials, url)
51
+ end
35
52
 
36
- encoded_sign = Auth.sign(secret_key, Auth.generate_signature(signature_options))
37
53
 
38
- headers = {
39
- "Authorization" => "Qiniu #{access_key}:#{encoded_sign}",
40
- "Content-Type" => "application/json"
41
- }
54
+ def update_stream(credentials, stream_id, options = {})
55
+ url = "/streams/" + stream_id
42
56
 
43
- response = HTTParty.post(url, :headers => headers, :body => body.to_json)
57
+ body = {}
58
+ body[:publishKey] = options[:publish_key]
59
+ body[:publishSecurity] = options[:publish_security] == "static" ? "static" : "dynamic"
60
+ body[:disabled] = options[:disabled]
44
61
 
45
- if response.code == 200
46
- response.parsed_response
47
- else
48
- raise ResponseError.new("Pili API Request Error", response)
49
- end
62
+ body.delete_if { |k, v| v.nil? }
63
+
64
+ Stream.new credentials, RPC.post(credentials, url, body)
50
65
  end
51
66
 
52
67
 
53
- def delete(access_key, secret_key, url)
54
- signature_options = {
55
- :url => url,
56
- :method => "DELETE"
57
- }
68
+ def delete_stream(credentials, stream_id)
69
+ url = "/streams/" + stream_id
70
+ RPC.delete(credentials, url)
71
+ end
58
72
 
59
- encoded_sign = Auth.sign(secret_key, Auth.generate_signature(signature_options))
60
73
 
61
- headers = { "Authorization" => "Qiniu #{access_key}:#{encoded_sign}" }
74
+ def get_stream_segments(credentials, stream_id, options = {})
75
+ url = "/streams/#{stream_id}/segments"
62
76
 
63
- response = HTTParty.delete(url, :headers => headers)
77
+ url += "?start=#{options[:start]}" if options[:start].is_a?(Fixnum)
78
+ url += "&end=#{options[:end]}" if options[:end].is_a?(Fixnum)
79
+ url += "&limit=#{options[:limit]}" if options[:limit].is_a?(Fixnum)
64
80
 
65
- if response.code == 204
66
- response.parsed_response
67
- else
68
- raise ResponseError.new("Pili API Request Error", response)
69
- end
81
+ response = RPC.get(credentials, url)
82
+ response["segments"] || []
83
+ end
84
+
85
+
86
+ def save_stream_as(credentials, stream_id, name, format, start_time, end_time, notify_url = nil)
87
+ url = "/streams/" + stream_id + "/saveas"
88
+
89
+ body = {}
90
+ body[:name] = name
91
+ body[:format] = format
92
+ body[:start] = start_time
93
+ body[:end] = end_time
94
+ body[:notifyUrl] = notify_url
95
+
96
+ body.delete_if { |k, v| v.nil? }
97
+
98
+ RPC.post(credentials, url, body)
70
99
  end
71
100
 
101
+
102
+ def snapshot(credentials, stream_id, name, format, options = {})
103
+ url = "/streams/" + stream_id + '/snapshot'
104
+
105
+ body = {}
106
+ body[:name] = name
107
+ body[:format] = format
108
+ body[:time] = options[:time]
109
+ body[:notifyUrl] = options[:notify_url]
110
+
111
+ body.delete_if { |k, v| v.nil? }
112
+
113
+ RPC.post(credentials, url, body)
114
+ end
115
+
116
+
72
117
  end
73
118
  end
74
119
  end
data/lib/pili/config.rb CHANGED
@@ -3,20 +3,23 @@ module Pili
3
3
  module Config
4
4
  class << self
5
5
 
6
- API_SCHEME = "http"
7
- API_HOST = "pili.qiniuapi.com"
8
- API_VERSION = "v1"
6
+ @@settings = {
7
+ :api_scheme => "http",
8
+ :api_host => "pili.qiniuapi.com",
9
+ :api_version => "v1",
10
+ :origin => "ORIGIN"
11
+ }
9
12
 
10
- # def init(options = {})
11
- # @settings = DEFAULT_OPTIONS.merge!(options)
12
- # REQUIRED_OPTION_KEYS.each do |opt|
13
- # raise("You did not provide both required args. Please provide the #{opt}.") unless @settings.has_key?(opt)
14
- # end
15
- # @settings
16
- # end
13
+ def init(options = {})
14
+ @@settings.merge!(options)
15
+ end
17
16
 
18
17
  def api_base_url
19
- "#{API_SCHEME}://#{API_HOST}/#{API_VERSION}"
18
+ "#{@@settings[:api_scheme]}://#{@@settings[:api_host]}/#{@@settings[:api_version]}"
19
+ end
20
+
21
+ def origin
22
+ @@settings[:origin]
20
23
  end
21
24
 
22
25
  end
@@ -4,7 +4,17 @@ require 'base64'
4
4
  require 'uri'
5
5
 
6
6
  module Pili
7
- module Auth
7
+ class Credentials
8
+
9
+ attr_reader :access_key, :secret_key
10
+
11
+
12
+ def initialize(access_key, secret_key)
13
+ @access_key = access_key
14
+ @secret_key = secret_key
15
+ end
16
+
17
+
8
18
  class << self
9
19
 
10
20
  def base64_url_encode(string)
data/lib/pili/hub.rb ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ module Pili
3
+ class Hub
4
+
5
+ attr_reader :credentials, :hub_name
6
+
7
+
8
+ def initialize(credentials, hub_name)
9
+ @credentials = credentials
10
+ @hub_name = hub_name
11
+ end
12
+
13
+
14
+ def create_stream(options = {})
15
+ API.create_stream(@credentials, @hub_name, options)
16
+ end
17
+
18
+
19
+ def get_stream(stream_id)
20
+ API.get_stream(@credentials, stream_id)
21
+ end
22
+
23
+
24
+ def list_streams(options = {})
25
+ API.list_streams(@credentials, @hub_name, options)
26
+ end
27
+
28
+ end
29
+ end
data/lib/pili/rpc.rb ADDED
@@ -0,0 +1,80 @@
1
+ # coding: utf-8
2
+ require 'httparty'
3
+
4
+ module Pili
5
+ module RPC
6
+ class << self
7
+
8
+ def get(credentials, url)
9
+ url = Config.api_base_url + url
10
+
11
+ signature_options = {
12
+ :url => url,
13
+ :method => "GET"
14
+ }
15
+
16
+ encoded_sign = Credentials.sign(credentials.secret_key, Credentials.generate_signature(signature_options))
17
+
18
+ headers = { "Authorization" => "Qiniu #{credentials.access_key}:#{encoded_sign}" }
19
+
20
+ response = HTTParty.get(url, :headers => headers)
21
+
22
+ if response.code == 200
23
+ response.parsed_response
24
+ else
25
+ raise ResponseError.new("Pili API Request Error", response)
26
+ end
27
+ end
28
+
29
+
30
+ def post(credentials, url, body)
31
+ url = Config.api_base_url + url
32
+
33
+ signature_options = {
34
+ :url => url,
35
+ :content_type => "application/json",
36
+ :method => "POST",
37
+ :body => body
38
+ }
39
+
40
+ encoded_sign = Credentials.sign(credentials.secret_key, Credentials.generate_signature(signature_options))
41
+
42
+ headers = {
43
+ "Authorization" => "Qiniu #{credentials.access_key}:#{encoded_sign}",
44
+ "Content-Type" => "application/json"
45
+ }
46
+
47
+ response = HTTParty.post(url, :headers => headers, :body => body.to_json)
48
+
49
+ if response.code == 200
50
+ response.parsed_response
51
+ else
52
+ raise ResponseError.new("Pili API Request Error", response)
53
+ end
54
+ end
55
+
56
+
57
+ def delete(credentials, url)
58
+ url = Config.api_base_url + url
59
+
60
+ signature_options = {
61
+ :url => url,
62
+ :method => "DELETE"
63
+ }
64
+
65
+ encoded_sign = Credentials.sign(credentials.secret_key, Credentials.generate_signature(signature_options))
66
+
67
+ headers = { "Authorization" => "Qiniu #{credentials.access_key}:#{encoded_sign}" }
68
+
69
+ response = HTTParty.delete(url, :headers => headers)
70
+
71
+ if response.code == 204
72
+ response.parsed_response
73
+ else
74
+ raise ResponseError.new("Pili API Request Error", response)
75
+ end
76
+ end
77
+
78
+ end
79
+ end
80
+ end
data/lib/pili/stream.rb CHANGED
@@ -2,16 +2,12 @@
2
2
  module Pili
3
3
  class Stream
4
4
 
5
- LIVE_URL_ORIGIN_KEY = "ORIGIN"
6
-
7
- attr_reader :client
8
- attr_reader :id, :created_at, :updated_at, :title, :hub, :profiles, :hosts
9
-
5
+ attr_reader :credentials, :id, :created_at, :updated_at, :title, :hub, :profiles, :hosts
10
6
  attr_accessor :publish_key, :publish_security, :disabled
11
7
 
12
8
 
13
- def initialize(client, options = {})
14
- @client = client
9
+ def initialize(credentials, options = {})
10
+ @credentials = credentials
15
11
  @id = options["id"]
16
12
  @title = options["title"]
17
13
  @hub = options["hub"]
@@ -27,46 +23,32 @@ module Pili
27
23
 
28
24
 
29
25
  def status
30
- url = Config.api_base_url + "/streams/#{@id}/status"
31
- API.get(@client.access_key, @client.secret_key, url)
26
+ API.get_stream_status(@credentials, @id)
32
27
  end
33
28
 
34
29
 
35
30
  def update(options = {})
36
- url = Config.api_base_url + "/streams/" + @id
37
-
38
- body = {}
39
- body[:publishKey] = options[:publish_key]
40
- body[:publishSecurity] = options[:publish_security] == "static" ? "static" : "dynamic"
41
- body[:disabled] = options[:disabled]
31
+ API.update_stream(@credentials, @id, self.to_h.merge!(options))
32
+ end
42
33
 
43
- body.delete_if { |k, v| v.nil? }
44
34
 
45
- stream = API.post(@client.access_key, @client.secret_key, url, body)
35
+ def enable
36
+ API.update_stream(@credentials, @id, disabled: false)
37
+ end
46
38
 
47
- @publish_key = stream["publishKey"]
48
- @publish_security = stream["publishSecurity"]
49
- @disabled = stream["disabled"]
50
- @updated_at = stream["updatedAt"]
51
39
 
52
- self
40
+ def disable
41
+ API.update_stream(@credentials, @id, disabled: true)
53
42
  end
54
43
 
55
44
 
56
45
  def delete
57
- url = Config.api_base_url + "/streams/" + @id
58
- API.delete(@client.access_key, @client.secret_key, url)
46
+ API.delete_stream(@credentials, @id)
59
47
  end
60
48
 
61
49
 
62
50
  def segments(options = {})
63
- url = Config.api_base_url + "/streams/#{@id}/segments"
64
-
65
- url += "?start=#{options[:start]}" if options[:start].is_a?(Fixnum)
66
- url += "&end=#{options[:end]}" if options[:end].is_a?(Fixnum)
67
-
68
- response = API.get(@client.access_key, @client.secret_key, url)
69
- response["segments"] || []
51
+ API.get_stream_segments(@credentials, @id, options)
70
52
  end
71
53
 
72
54
 
@@ -77,19 +59,32 @@ module Pili
77
59
  return "rtmp://#{rtmp_publish_host}/#{@hub}/#{@title}?key=#{@publish_key}"
78
60
  else
79
61
  nonce = Time.now.to_i
80
- token = Auth.sign(publish_key, "/#{@hub}/#{@title}?nonce=#{nonce}")
62
+ token = Credentials.sign(publish_key, "/#{@hub}/#{@title}?nonce=#{nonce}")
81
63
  return "rtmp://#{rtmp_publish_host}/#{@hub}/#{@title}?nonce=#{nonce}&token=#{token}"
82
64
  end
83
65
  end
84
66
 
85
67
 
86
68
  def rtmp_live_urls
87
- rtmp_play_host = @hosts["play"]["rtmp"]
69
+ live_rtmp_host = @hosts["live"]["rtmp"]
88
70
 
89
- urls = { LIVE_URL_ORIGIN_KEY => "rtmp://#{rtmp_play_host}/#{@hub}/#{@title}" }
71
+ urls = { Config.origin => "rtmp://#{live_rtmp_host}/#{@hub}/#{@title}" }
90
72
 
91
73
  @profiles.each do |profile|
92
- urls[profile] = "rtmp://#{rtmp_play_host}/#{@hub}/#{@title}@#{profile}"
74
+ urls[profile] = "rtmp://#{live_rtmp_host}/#{@hub}/#{@title}@#{profile}"
75
+ end
76
+
77
+ urls
78
+ end
79
+
80
+
81
+ def http_flv_live_urls
82
+ live_http_host = @hosts["live"]["http"]
83
+
84
+ urls = { Config.origin => "http://#{live_http_host}/#{@hub}/#{@title}.flv" }
85
+
86
+ @profiles.each do |profile|
87
+ urls[profile] = "http://#{live_http_host}/#{@hub}/#{@title}@#{profile}.flv"
93
88
  end
94
89
 
95
90
  urls
@@ -97,12 +92,12 @@ module Pili
97
92
 
98
93
 
99
94
  def hls_live_urls
100
- hls_play_host = @hosts["play"]["hls"]
95
+ live_http_host = @hosts["live"]["http"]
101
96
 
102
- urls = { LIVE_URL_ORIGIN_KEY => "http://#{hls_play_host}/#{@hub}/#{@title}.m3u8" }
97
+ urls = { Config.origin => "http://#{live_http_host}/#{@hub}/#{@title}.m3u8" }
103
98
 
104
99
  @profiles.each do |profile|
105
- urls[profile] = "http://#{hls_play_host}/#{@hub}/#{@title}@#{profile}.m3u8"
100
+ urls[profile] = "http://#{live_http_host}/#{@hub}/#{@title}@#{profile}.m3u8"
106
101
  end
107
102
 
108
103
  urls
@@ -110,12 +105,12 @@ module Pili
110
105
 
111
106
 
112
107
  def hls_playback_urls(start_second, end_second)
113
- hls_play_host = @hosts["play"]["hls"]
108
+ playback_http_host = @hosts["playback"]["http"]
114
109
 
115
- urls = { LIVE_URL_ORIGIN_KEY => "http://#{hls_play_host}/#{@hub}/#{@title}.m3u8?start=#{start_second}&end=#{end_second}" }
110
+ urls = { Config.origin => "http://#{playback_http_host}/#{@hub}/#{@title}.m3u8?start=#{start_second}&end=#{end_second}" }
116
111
 
117
112
  @profiles.each do |profile|
118
- urls[profile] = "http://#{hls_play_host}/#{@hub}/#{@title}@#{profile}.m3u8?start=#{start_second}&end=#{end_second}"
113
+ urls[profile] = "http://#{playback_http_host}/#{@hub}/#{@title}@#{profile}.m3u8?start=#{start_second}&end=#{end_second}"
119
114
  end
120
115
 
121
116
  urls
@@ -138,19 +133,30 @@ module Pili
138
133
  end
139
134
 
140
135
 
141
- def save_as(name, format, start_time, end_time, options = {})
142
- url = Config.api_base_url + "/streams/" + @id + "/saveas"
136
+ def snapshot(name, format, options = {})
137
+ API.snapshot(@credentials, @id, name, format, options)
138
+ end
139
+
143
140
 
144
- body = {}
145
- body[:name] = name
146
- body[:start] = start_time
147
- body[:end] = end_time
148
- body[:format] = format
149
- body[:notifyUrl] = options[:notify_url]
141
+ def save_as(name, format, start_time, end_time, notify_url = nil)
142
+ API.save_stream_as(@credentials, @id, name, format, start_time, end_time, notify_url)
143
+ end
150
144
 
151
- body.delete_if { |k, v| v.nil? }
152
145
 
153
- API.post(@client.access_key, @client.secret_key, url, body)
146
+ def to_h
147
+ {
148
+ credentials: @credentials,
149
+ id: @id,
150
+ title: @title,
151
+ hub: @hub,
152
+ profiles: @profiles,
153
+ publish_key: @publish_key,
154
+ publish_security: @publish_security,
155
+ disabled: @disabled,
156
+ hosts: @hosts,
157
+ created_at: @created_at,
158
+ updated_at: @updated_at
159
+ }
154
160
  end
155
161
 
156
162
  end