bitmovin-api 0.0.1.pre

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,23 @@
1
+ require File.expand_path('../lib/bitmovin/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'bitmovin-api'
5
+ s.version = Bitmovin::VERSION
6
+ s.date = '2017-02-09'
7
+ s.summary = "Bitmovin api client"
8
+ s.description = "Simple ruby wrapper for bitmovin encoding service api. Written in pure ruby with no runtime dependencies."
9
+ s.authors = ["DevilsNightsix"]
10
+ s.email = 'eeendi94@gmail.com'
11
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
12
+ s.require_paths = ["lib"]
13
+ s.homepage = 'http://rubygems.org/gems/bitmovin-api'
14
+ s.license = 'MIT'
15
+ s.add_development_dependency "yard"
16
+ s.add_development_dependency "rake"
17
+ s.add_development_dependency "byebug"
18
+ s.add_development_dependency "guard"
19
+ s.add_development_dependency "guard-minitest"
20
+ s.add_development_dependency "apib-mock_server"
21
+ s.add_development_dependency "webmock"
22
+ s.add_development_dependency "minitest-color"
23
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bitmovin/helpers'
4
+ require 'bitmovin/input'
5
+ require 'bitmovin/output'
6
+ require 'bitmovin/encoding_profile'
7
+ require 'bitmovin/transfer_job'
8
+ require 'bitmovin/job'
9
+
10
+ module Bitmovin
11
+
12
+ API_URL = 'https://portal.bitcodin.com/api'
13
+ API_URI = URI(API_URL)
14
+
15
+ @@api_key = nil
16
+ @@http = Net::HTTP.new API_URI.host, API_URI.port
17
+ @@http.use_ssl = API_URI.scheme == "https"
18
+
19
+ class << self
20
+ def api_key=(key)
21
+ @@api_key = key
22
+ end
23
+
24
+ def http
25
+ @@http
26
+ end
27
+
28
+ def api_key
29
+ @@api_key
30
+ end
31
+ end
32
+
33
+ class ApiParameterEmptyError < StandardError
34
+
35
+ def initialize(msg = "Is required", parameter)
36
+ @parameter = parameter
37
+ @msg = msg
38
+ end
39
+ end
40
+ end
File without changes
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../helpers', __FILE__)
4
+
5
+ module Bitmovin
6
+ # Represents a bitmovin encoding profile
7
+ # @see https://bitmovin.com/encoding-documentation/encoder-api-reference-documentation/#/reference/encoding-profiles Bitmovin Encoding Profiles docs
8
+ class EncodingProfile
9
+
10
+ include Bitmovin::Helpers
11
+
12
+ ATTRIBUTES = %i{
13
+ encoding_profile_id
14
+ video_stream_configs
15
+ audio_stream_configs
16
+ watermark_config
17
+ created_at
18
+ type
19
+ name
20
+ }
21
+
22
+ ATTRIBUTES.each do |_attr|
23
+ define_method _attr do
24
+ @details[_attr]
25
+ end
26
+
27
+ define_method :"#{_attr}=" do |value|
28
+ @details[_attr] = value
29
+ end
30
+ end
31
+
32
+ ##
33
+ # @param params Encoding profile video & audio configurations
34
+ # * :name Name of new Encoding profile
35
+ # * :rotation Rotation of the video in degrees. A positive value will rotate the video clockwise and a negative one counter clockwise.
36
+ # * :segment_length Only available using standard speed. Defines the length of a segment. Must be a value between 1 and 9 seconds.
37
+ # * :video_stream_configs An array of video profile configs
38
+ # * :default_stream_id ID of the video stream which should be encoded
39
+ # * :representation_id ID of the video stream config
40
+ # * :bitrate Bitrate of the video stream. Value must be in the range from 32000 to 20000000
41
+ # * :profile Profile which should be used to encode video stream. Possible values are: baseline, main, high
42
+ # * :preset Preset which should be used to encode video stream. Possible values are: standard, professional, premium
43
+ # * :height Video-Width in px, must be in the range from 128 to 7680
44
+ # * :width Video-Height in px, must be in the range from 96 to 4320
45
+ # * :rate Only available using standard speed. The sample rate the encoded video should have in FPS. Values must be in the range from 1 to 120
46
+ # * :codec Only available using premium speed. Sets the video codec used for encoding. Possible values are: h264, hevc. Default value is h264.
47
+ # * :b_frames Sets the amount of B-Frames. Valid value range: 0 - 16
48
+ # * :ref_frames Sets the amount of Reference-Frames. Valid value range: 0 - 16
49
+ # * :qp_min Sets the minimum of quantization-factor. Valid value range: 0 - 69
50
+ # * :qp_max Sets the maximum of quantization-factor. Valid value range: 0 - 69
51
+ # * :mv_prediction_mode Sets the Motion Vector Prediction Mode. Valid values: none, spatial, temporal, auto
52
+ # * :mv_search_range_max Sets the maximum Motion-Vector-Search-Range. Valid value range: 16 - 24
53
+ # * :no_cabac Disable CABAC.
54
+ # * :audio_stream_configs An array of audio profile configs
55
+ # * :default_stream_id ID of the audio stream which should be encoded
56
+ # * :representation_id ID of the audio stream config
57
+ # * :bitrate Bitrate of the audio stream. Values must be in the range from 8000 to 256000
58
+ # * :rate The sample rate the encoded audio should have in Hz. Possible values are: 0, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000
59
+ # * :watermark_config A watermark config
60
+ # * :top Distance between the top of the watermark image and the top of the input video
61
+ # * :left Distance between the left side of the watermark image and the left side of the input video
62
+ # * :bottom Distance between the bottom of the watermark image and the bottom of the input video
63
+ # * :right Distance between the right of the watermark image and the right of the input video
64
+ # * :cropping_config
65
+ # * :top Amount of pixel which will be cropped of the input video from the top.
66
+ # * :left Amount of pixel which will be cropped of the input video from the left side.
67
+ # * :bottom Amount of pixel which will be cropped of the input video from the bottom.
68
+ # * :right Amount of pixel which will be cropped of the input video from the right side.
69
+ #
70
+ def initialize(params={})
71
+ @details = params
72
+ end
73
+
74
+ ##
75
+ # Create encoding profile with params given within initialization
76
+ #
77
+ # return [Bitmovin::EncodingProfile] create bitmovin encoding profile
78
+ def create
79
+ make_create_request
80
+ self
81
+ end
82
+
83
+ ##
84
+ # @param params Encoding profile video & audio configurations
85
+ # * :name Name of new Encoding profile
86
+ # * :rotation Rotation of the video in degrees. A positive value will rotate the video clockwise and a negative one counter clockwise.
87
+ # * :segment_length Only available using standard speed. Defines the length of a segment. Must be a value between 1 and 9 seconds.
88
+ # * :video_stream_configs An array of video profile configs
89
+ # * :default_stream_id ID of the video stream which should be encoded
90
+ # * :representation_id ID of the video stream config
91
+ # * :bitrate Bitrate of the video stream. Value must be in the range from 32000 to 20000000
92
+ # * :profile Profile which should be used to encode video stream. Possible values are: baseline, main, high
93
+ # * :preset Preset which should be used to encode video stream. Possible values are: standard, professional, premium
94
+ # * :height Video-Width in px, must be in the range from 128 to 7680
95
+ # * :width Video-Height in px, must be in the range from 96 to 4320
96
+ # * :rate Only available using standard speed. The sample rate the encoded video should have in FPS. Values must be in the range from 1 to 120
97
+ # * :codec Only available using premium speed. Sets the video codec used for encoding. Possible values are: h264, hevc. Default value is h264.
98
+ # * :b_frames Sets the amount of B-Frames. Valid value range: 0 - 16
99
+ # * :ref_frames Sets the amount of Reference-Frames. Valid value range: 0 - 16
100
+ # * :qp_min Sets the minimum of quantization-factor. Valid value range: 0 - 69
101
+ # * :qp_max Sets the maximum of quantization-factor. Valid value range: 0 - 69
102
+ # * :mv_prediction_mode Sets the Motion Vector Prediction Mode. Valid values: none, spatial, temporal, auto
103
+ # * :mv_search_range_max Sets the maximum Motion-Vector-Search-Range. Valid value range: 16 - 24
104
+ # * :no_cabac Disable CABAC.
105
+ # * :audio_stream_configs An array of audio profile configs
106
+ # * :default_stream_id ID of the audio stream which should be encoded
107
+ # * :representation_id ID of the audio stream config
108
+ # * :bitrate Bitrate of the audio stream. Values must be in the range from 8000 to 256000
109
+ # * :rate The sample rate the encoded audio should have in Hz. Possible values are: 0, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000
110
+ # * :watermark_config A watermark config
111
+ # * :top Distance between the top of the watermark image and the top of the input video
112
+ # * :left Distance between the left side of the watermark image and the left side of the input video
113
+ # * :bottom Distance between the bottom of the watermark image and the bottom of the input video
114
+ # * :right Distance between the right of the watermark image and the right of the input video
115
+ # * :cropping_config
116
+ # * :top Amount of pixel which will be cropped of the input video from the top.
117
+ # * :left Amount of pixel which will be cropped of the input video from the left side.
118
+ # * :bottom Amount of pixel which will be cropped of the input video from the bottom.
119
+ # * :right Amount of pixel which will be cropped of the input video from the right side.
120
+ #
121
+ def self.create(params={})
122
+ new(params).create
123
+ end
124
+
125
+ ##
126
+ # Get encoding profile details as hash
127
+ # @param reload [Boolean] Reload details from server
128
+ # @return [Hash] encoding profile details
129
+ #
130
+ def details(reload = false)
131
+ return @details unless reload
132
+
133
+ reload_details
134
+ end
135
+
136
+ class << self
137
+ include Bitmovin::Helpers
138
+
139
+ ##
140
+ # Get list of available encoding profiles by pages per 10
141
+ # @param page [Integer] number of page
142
+ # @return [Array<Bitmovin::EncodingProfile>] array of encoding profiles
143
+ #
144
+ def list(page = 1)
145
+ get = Net::HTTP::Get.new "/api/encoding-profiles/#{page}", initheaders = headers
146
+
147
+ response = Bitmovin.http.request get
148
+
149
+ json = prepare_response_json(response.body)
150
+
151
+ json[:profiles].map { |p| Bitmovin::EncodingProfile.new(p) }
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ def reload_details
158
+ get = Net::HTTP::Get.new "/api/encoding-profile/#{encoding_profile_id}"
159
+
160
+ response = Bitmovin.http.request get
161
+
162
+ @details = prepare_response_json(response.body)
163
+ @details
164
+ end
165
+
166
+ def make_create_request
167
+ payload = prepare_request_json(@details)
168
+
169
+ post = Net::HTTP::Post.new "/api/encoding-profile/create", initheaders = headers
170
+ post.body = payload
171
+
172
+ response = Bitmovin.http.request post
173
+
174
+ @details = prepare_response_json(response.body)
175
+ self
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Bitmovin
6
+ module Helpers
7
+
8
+ S3_BUCKET_SUBDOMAIN_REGEX = /^https?:\/\/(.*)\.s3/.freeze
9
+ S3_BUCKET_IN_URL_REGEX = /^https?:\/\/s3\.amazonaws\.com\/([\w\-\_]+)\//.freeze
10
+
11
+ S3_OBJECT_KEY_SUBDOMAIN_REGEX = /^https?:\/\/(?:.*)\.s3\.amazonaws\.com\/(.*)/.freeze
12
+ S3_OBJECT_KEY_IN_URL_REGEX = /^https?:\/\/s3\.amazonaws\.com\/[\w\-\_]+\/(.*)/.freeze
13
+
14
+ ##
15
+ # Converting passed hash to be acceptable by bitmivin api
16
+ #
17
+ # @param hash [Hash] the hash to be converted
18
+ #
19
+ # @return [String] valid json string
20
+ #
21
+ def prepare_request_json(hash)
22
+ json = deep_camelize_keys(hash)
23
+ JSON.generate(json)
24
+ end
25
+
26
+ ##
27
+ # Converting bitmovin api response json to ruby hash
28
+ #
29
+ # @param json [String] json string with camelcased keys
30
+ #
31
+ # @return [Hash] parsed api response with snakecased keys
32
+ #
33
+ def prepare_response_json(json)
34
+ json = JSON.parse json
35
+
36
+ if json.is_a?(Hash)
37
+ deep_underscore_keys json
38
+ elsif json.is_a?(Array)
39
+ json.map { |ji| deep_underscore_keys(ji) }
40
+ end
41
+ end
42
+
43
+ ##
44
+ # Converts hash keys to string in camelCase
45
+ # @param subject [Hash] Hash to be converted
46
+ # @param first_letter_in_uppercase [Boolean] Is first letter should be uppercased
47
+ #
48
+ # @return [Hash] converted hash with stringified keys in camelCase
49
+ def deep_camelize_keys(subject, first_letter_in_uppercase = false)
50
+ init_value = Hash.new
51
+ subject.inject init_value do |acc, props|
52
+ acc[camelize(props.first.to_s, first_letter_in_uppercase).to_sym] = case props.last
53
+ when Hash then deep_camelize_keys(props.last, first_letter_in_uppercase)
54
+ when Array then props.last.map { |i| i.is_a?(Hash) ? deep_camelize_keys(i, first_letter_in_uppercase) : i }
55
+ else props.last
56
+ end
57
+ acc
58
+ end
59
+ end
60
+
61
+ ##
62
+ # Converts hash keys to symbols in snake_case
63
+ # @param subject [Hash] Hash to be converted
64
+ #
65
+ # @return [Hash] converted hash with symbolized keys in snake_case
66
+ def deep_underscore_keys(subject)
67
+ init_value = subject.class.new if subject.is_a?(Hash) || subject.is_a?(Array)
68
+ subject.inject init_value do |acc, props|
69
+ acc[underscore(props.first.to_s).to_sym] = case props.last
70
+ when Hash then deep_underscore_keys(props.last)
71
+ when Array then props.last.map { |i| i.is_a?(Hash) ? deep_underscore_keys(i) : i }
72
+ else props.last
73
+ end
74
+ acc
75
+ end
76
+ end
77
+
78
+
79
+ ##
80
+ # Extracts AWS S3 bucket name from url
81
+ #
82
+ # @param url [String] url to AWS S3 file
83
+ #
84
+ # @return [String] name of bucket
85
+ #
86
+ def extract_bucket(url)
87
+ unescaped = URI.unescape(url)
88
+
89
+ bucket = unescaped.match(S3_BUCKET_SUBDOMAIN_REGEX)[1] rescue nil
90
+ bucket ||= unescaped.match(S3_BUCKET_IN_URL_REGEX)[1] rescue nil
91
+
92
+ bucket
93
+ end
94
+
95
+ ##
96
+ # Extracts AWS S3 file name from url
97
+ #
98
+ # @param url [String] url to AWS S3 file
99
+ #
100
+ # @return [String] name of file with containing folders
101
+ #
102
+ def extract_object_key(url)
103
+ unescaped = URI.unescape(url)
104
+
105
+ file = unescaped.match(S3_OBJECT_KEY_SUBDOMAIN_REGEX)[1] rescue nil
106
+ file ||= unescaped.match(S3_OBJECT_KEY_IN_URL_REGEX)[1] rescue nil
107
+
108
+ file
109
+ end
110
+
111
+ protected
112
+
113
+ def headers
114
+ @headers ||= {
115
+ 'Content-Type' => "application/json",
116
+ 'bitcodin-api-version' => 'v1',
117
+ 'bitcodin-api-key' => Bitmovin.api_key
118
+ }
119
+ end
120
+
121
+
122
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
123
+ if first_letter_in_uppercase
124
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
125
+ else
126
+ lower_case_and_underscored_word[0] + camelize(lower_case_and_underscored_word)[1..-1]
127
+ end
128
+ end
129
+
130
+ def underscore(str)
131
+ str.gsub(/[A-Z\s]/) { "_#{$&.downcase}" }
132
+ end
133
+
134
+ end
135
+ end
136
+
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../helpers', __FILE__)
4
+
5
+ module Bitmovin
6
+ # Represents a bitmovin input
7
+ # @see https://bitmovin.com/encoding-documentation/encoder-api-reference-documentation/#/reference/inputs/ Bitmovin Input docs
8
+ class Input
9
+
10
+ include Bitmovin::Helpers
11
+
12
+ ATTRIBUTES = %i{
13
+ input_id
14
+ async
15
+ type
16
+ url
17
+ username
18
+ password
19
+ region
20
+ bucket
21
+ object_key
22
+ access_key
23
+ secret_key
24
+ account_name
25
+ account_key
26
+ container
27
+ min_bandwidth
28
+ max_bandwidth
29
+ }
30
+
31
+ ATTRIBUTES.each do |_attr|
32
+ define_method _attr do
33
+ @params[_attr]
34
+ end
35
+
36
+ define_method :"#{_attr}=" do |value|
37
+ @params[_attr] = value
38
+ end
39
+ end
40
+
41
+
42
+ attr_reader :params, :url
43
+
44
+ #
45
+ # @overload initialize(url, params)
46
+ # @param url [String] url of input for URL, S3 or Aspera inputs
47
+ # @param params [String] input params
48
+ # @option params {Boolean] :async Create input async
49
+ # @option params [String] :type Type of input
50
+ # @option params [String] :username Basic auth username
51
+ # @option params [String] :password Basic auth password
52
+ # @option params [String] :region ('us-east-1') S3 bucket region
53
+ # @option params [String] :bucket S3 bucket name for s3 input, also can be infered from url
54
+ # @option params [String] :object_key S3 object name with containing folder, can be infered from url
55
+ # @option params [String] :access_key S3 or GCS access key, required for S3 or GCS inputs
56
+ # @option params [String] :secret_key S3 or GCS secret, required for S3 or GCS inputs
57
+ # @option params [String] :account_name MS Azure account name, required for Azure inputs
58
+ # @option params [String] :account_key MS Azure account key, required for Azure inputs
59
+ # @option params [String] :container MS Azure storage container name
60
+ # @option params [String] :min_bandwidth, Minimal download bandwidth
61
+ # @option params [String] :max_bandwidth, Maximal download bandwidth
62
+ #
63
+ # @overload initialize(params)
64
+ # @param params [String] input params
65
+ # @option params {Boolean] :async Create input async
66
+ # @option params [String] :type Type of input
67
+ # @option params [String] :url Aspera/Azure file url
68
+ # @option params [String] :username Basic auth username
69
+ # @option params [String] :password Basic auth password
70
+ # @option params [String] :region ('us-east-1') S3 bucket region
71
+ # @option params [String] :bucket S3 bucket name for s3 input, also can be infered from url
72
+ # @option params [String] :object_key S3 object name with containing folder, can be infered from url
73
+ # @option params [String] :access_key S3 or GCS access key, required for S3 or GCS inputs
74
+ # @option params [String] :secret_key S3 or GCS secret, required for S3 or GCS inputs
75
+ # @option params [String] :account_name MS Azure account name, required for Azure inputs
76
+ # @option params [String] :account_key MS Azure account key, required for Azure inputs
77
+ # @option params [String] :container MS Azure storage container name
78
+ # @option params [String] :min_bandwidth, Minimal download bandwidth
79
+ # @option params [String] :max_bandwidth, Maximal download bandwidth
80
+ #
81
+ #
82
+ # @return [Hash] Input details as a hash
83
+ #
84
+ def initialize(*args)
85
+ @params = args.pop
86
+
87
+ @url = args.pop if args.length == 1
88
+
89
+ if @url
90
+ @params[:bucket] = extract_bucket(url) if !@params[:bucket] && @params[:type] == "s3"
91
+ @params[:object_key] = extract_object_key(url) if !@params[:object_key] && @params[:type] == "s3"
92
+ @params[:url]
93
+ end
94
+ end
95
+
96
+ ##
97
+ # Creates a new bitmovin input
98
+ #
99
+ # @param (#initialize)
100
+ #
101
+ # @return [Bitmovin::Input] Bitmovin Input details
102
+ #
103
+ def self.create(*args)
104
+ new(*args).create
105
+ end
106
+
107
+ ##
108
+ # Creates a new bitmovin input with params given within initialization
109
+ # @return [Bitmovin::Input] Bitmovin Input details
110
+ #
111
+ def create
112
+ make_create_request
113
+ end
114
+
115
+ ##
116
+ # Get bitmovin input details
117
+ # @param reload [Boolean] force data reload from server
118
+ def details(reload = false)
119
+ return @params if !reload && @params
120
+
121
+ reload_details
122
+ end
123
+
124
+ private
125
+
126
+ ##
127
+ #@private
128
+ def make_create_request
129
+ if %w{s3 gcs}.include? params[:type]
130
+ raise Bitmovin::ApiParameterEmptyError.new(parameter = :access_key) unless params[:access_key]
131
+ raise Bitmovin::ApiParameterEmptyError.new(parameter = :secret_key) unless params[:secret_key]
132
+ end
133
+
134
+ payload = prepare_request_json(params)
135
+ path = params[:async] ? "/api/input/createasync" : "/api/input/create"
136
+ post = Net::HTTP::Post.new path, initheaders = headers
137
+ post.body = payload
138
+
139
+ response = Bitmovin.http.request post
140
+
141
+ @params = prepare_response_json(response.body)
142
+ self
143
+ rescue Net::HTTPRequestTimeOut => e
144
+ nil
145
+ end
146
+
147
+ ##
148
+ #@private
149
+ def reload_details
150
+ get = Net::HTTP::Get.new "/api/input/#{@params[:input_id]}", initheaders = headers
151
+
152
+ response = Bitmovin.http.request get
153
+
154
+ @params = prepare_response_json(response.body)
155
+ end
156
+ end
157
+ end