diff --git a/.oas-version b/.oas-version index 18b3114..15b989e 100644 --- a/.oas-version +++ b/.oas-version @@ -1 +1 @@ -1.10.4 +1.16.0 diff --git a/lib/shotstack/api/edit_api.rb b/lib/shotstack/api/edit_api.rb index 3ff55f2..1e573ee 100644 --- a/lib/shotstack/api/edit_api.rb +++ b/lib/shotstack/api/edit_api.rb @@ -85,6 +85,69 @@ def delete_template_with_http_info(id, opts = {}) return data, status_code, headers end + # Get Generation Status + # Get the status of an on-demand asset generation job created with the generate endpoint. Jobs are owner-scoped. **Base URL:** https://api.shotstack.io/edit/{version} + # @param id [String] The generation job id returned by the generate endpoint. + # @param [Hash] opts the optional parameters + # @return [Object] + def get_generate(id, opts = {}) + data, _status_code, _headers = get_generate_with_http_info(id, opts) + data + end + + # Get Generation Status + # Get the status of an on-demand asset generation job created with the generate endpoint. Jobs are owner-scoped. **Base URL:** <a href=\"#\">https://api.shotstack.io/edit/{version}</a> + # @param id [String] The generation job id returned by the generate endpoint. + # @param [Hash] opts the optional parameters + # @return [Array<(Object, Integer, Hash)>] Object data, response status code and response headers + def get_generate_with_http_info(id, opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: EditApi.get_generate ...' + end + # verify the required parameter 'id' is set + if @api_client.config.client_side_validation && id.nil? + fail ArgumentError, "Missing the required parameter 'id' when calling EditApi.get_generate" + end + # resource path + local_var_path = '/generate/{id}'.sub('{' + 'id' + '}', CGI.escape(id.to_s)) + + # query parameters + query_params = opts[:query_params] || {} + + # header parameters + header_params = opts[:header_params] || {} + # HTTP header 'Accept' (if needed) + header_params['Accept'] = @api_client.select_header_accept(['application/json']) + + # form parameters + form_params = opts[:form_params] || {} + + # http body (model) + post_body = opts[:debug_body] + + # return_type + return_type = opts[:debug_return_type] || 'Object' + + # auth_names + auth_names = opts[:debug_auth_names] || ['DeveloperKey'] + + new_options = opts.merge( + :operation => :"EditApi.get_generate", + :header_params => header_params, + :query_params => query_params, + :form_params => form_params, + :body => post_body, + :auth_names => auth_names, + :return_type => return_type + ) + + data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options) + if @api_client.config.debugging + @api_client.config.logger.debug "API called: EditApi#get_generate\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + # Get Render Status # Get the rendering status, temporary asset url and details of a render by ID. **Base URL:** https://api.shotstack.io/edit/{version} # @param id [String] The id of the timeline render task in UUID format @@ -284,6 +347,70 @@ def get_templates_with_http_info(opts = {}) return data, status_code, headers end + # Generate Asset + # Generate a single image, video or audio asset from a text prompt without rendering a full edit. Submit a prompt-bearing asset; the response is immediate when an identical asset has been generated before (results are cached by prompt, model and options), otherwise the job is queued and can be polled via the status endpoint. Generation is billed in credits per asset. Identical repeat requests resolve from the cache at no charge. **Base URL:** https://api.shotstack.io/edit/{version} + # @param [Hash] opts the optional parameters + # @option opts [PostGenerateRequest] :post_generate_request A prompt-bearing image, video or audio asset to generate. + # @return [PostGenerate200Response] + def post_generate(opts = {}) + data, _status_code, _headers = post_generate_with_http_info(opts) + data + end + + # Generate Asset + # Generate a single image, video or audio asset from a text prompt without rendering a full edit. Submit a prompt-bearing asset; the response is immediate when an identical asset has been generated before (results are cached by prompt, model and options), otherwise the job is queued and can be polled via the status endpoint. Generation is billed in credits per asset. Identical repeat requests resolve from the cache at no charge. **Base URL:** <a href=\"#\">https://api.shotstack.io/edit/{version}</a> + # @param [Hash] opts the optional parameters + # @option opts [PostGenerateRequest] :post_generate_request A prompt-bearing image, video or audio asset to generate. + # @return [Array<(PostGenerate200Response, Integer, Hash)>] PostGenerate200Response data, response status code and response headers + def post_generate_with_http_info(opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: EditApi.post_generate ...' + end + # resource path + local_var_path = '/generate' + + # query parameters + query_params = opts[:query_params] || {} + + # header parameters + header_params = opts[:header_params] || {} + # HTTP header 'Accept' (if needed) + header_params['Accept'] = @api_client.select_header_accept(['application/json']) + # HTTP header 'Content-Type' + content_type = @api_client.select_header_content_type(['application/json']) + if !content_type.nil? + header_params['Content-Type'] = content_type + end + + # form parameters + form_params = opts[:form_params] || {} + + # http body (model) + post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'post_generate_request']) + + # return_type + return_type = opts[:debug_return_type] || 'PostGenerate200Response' + + # auth_names + auth_names = opts[:debug_auth_names] || ['DeveloperKey'] + + new_options = opts.merge( + :operation => :"EditApi.post_generate", + :header_params => header_params, + :query_params => query_params, + :form_params => form_params, + :body => post_body, + :auth_names => auth_names, + :return_type => return_type + ) + + data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options) + if @api_client.config.debugging + @api_client.config.logger.debug "API called: EditApi#post_generate\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + # Render Asset # Queue and render the contents of an [Edit](#tocs_edit) as a video, image or audio file. **Rendering Process:** 1. **Validation**: The edit JSON is validated 2. **Download**: All assets are downloaded and cached 3. **Preprocessing**: Video assets are automatically processed to fix compatibility issues 4. **Rendering**: The timeline is rendered using the processed assets 5. **Output**: The final media file is generated and stored **Video Preprocessing:** Video assets undergo automatic preprocessing to ensure compatibility. You can force preprocessing by setting `\"transcode\": true` on video assets. See [Preprocessing](#preprocessing) for more details. **Base URL:** https://api.shotstack.io/edit/{version} # @param edit [Edit] The video, image or audio edit specified using JSON. diff --git a/lib/shotstack/models/asset.rb b/lib/shotstack/models/asset.rb index 59182bb..550a5da 100644 --- a/lib/shotstack/models/asset.rb +++ b/lib/shotstack/models/asset.rb @@ -22,6 +22,7 @@ def openapi_one_of [ :'AudioAsset', :'CaptionAsset', + :'Html5Asset', :'HtmlAsset', :'ImageAsset', :'ImageToVideoAsset', @@ -49,6 +50,7 @@ def openapi_discriminator_mapping :'audio' => :'AudioAsset', :'caption' => :'CaptionAsset', :'html' => :'HtmlAsset', + :'html5' => :'Html5Asset', :'image' => :'ImageAsset', :'image-to-video' => :'ImageToVideoAsset', :'luma' => :'LumaAsset', diff --git a/lib/shotstack/models/audio_asset.rb b/lib/shotstack/models/audio_asset.rb index 0c805f5..4d62d12 100644 --- a/lib/shotstack/models/audio_asset.rb +++ b/lib/shotstack/models/audio_asset.rb @@ -14,20 +14,29 @@ require 'time' module Shotstack - # The AudioAsset is used to add sound effects and audio at specific intervals on the timeline. The src must be a publicly accessible URL to an audio resource such as an mp3 file. + # The AudioAsset adds audio to a Clip. The audio can be sourced from a URL (`src`), generated from a text prompt (`prompt`), or both. At least one of `src` or `prompt` must be provided. - **Source URL:** set `src` to a publicly accessible audio URL (e.g. mp3). - **Generated speech:** set `prompt` to the spoken text and choose a text-to-speech `model`; set the voice via `options`. - **Generated music or SFX:** set `prompt` describing the sound and choose a music generation `model`. - **Both:** `src` acts as a preview placeholder while `prompt` drives generation — the audio is regenerated from the prompt at render time. Unchanged prompts and options resolve from the generation cache. - Use `model` to choose the generator and `options` to configure it. The generated `src` is filled in automatically. class AudioAsset # The type of asset - set to `audio` for audio assets. attr_accessor :type - # The audio source URL. The URL must be publicly accessible or include credentials. + # The audio source URL. The URL must be publicly accessible or include credentials. When `prompt` is also set, `src` serves as a preview placeholder and the audio is regenerated from the prompt at render time. attr_accessor :src + # A text prompt. For text-to-speech models the prompt is the spoken text; for music models it describes the sound to generate. The generated `src` is filled in automatically; an existing `src` is treated as a preview placeholder and replaced. + attr_accessor :prompt + + # The generation model to use when `prompt` is set (e.g. `polly-neural`, `elevenlabs-tts`, `elevenlabs-music`). Defaults to `elevenlabs-tts` (with a default voice) if omitted. Each model's available options are defined by the model registry. + attr_accessor :model + + # Model-specific generation settings. Valid keys and values depend on the chosen `model` and are defined by the model registry. Omitted options use the model's defaults. Unknown or invalid options are rejected. + attr_accessor :options + # The start trim point of the audio clip, in seconds (defaults to 0). Audio will start from the in trim point. The audio will play until the file ends or the Clip length is reached. attr_accessor :trim attr_accessor :volume - # Adjust the playback speed of the audio clip between 0 (paused) and 10 (10x normal speed), where 1 is normal speed (defaults to 1). Adjusting the speed will also adjust the duration of the clip and may require you to adjust the Clip length. For example, if you set speed to 0.5, the clip will need to be 2x as long to play the entire audio (i.e. original length / 0.5). If you set speed to 2, the clip will need to be half as long to play the entire audio (i.e. original length / 2). + # Adjust the playback speed of the audio clip between 0 (paused) and 10 (10x normal speed), where 1 is normal speed (defaults to 1). Adjusting the speed will also adjust the duration of the clip and may require you to adjust the Clip length. For example, if you set speed to 0.5, the clip will need to be 2x as long to play the entire audio (i.e. original length / 0.5). If you set speed to 2, the clip will need to be half as long to play the entire audio (i.e. original length / 2). attr_accessor :speed # The effect to apply to the audio asset @@ -60,6 +69,9 @@ def self.attribute_map { :'type' => :'type', :'src' => :'src', + :'prompt' => :'prompt', + :'model' => :'model', + :'options' => :'options', :'trim' => :'trim', :'volume' => :'volume', :'speed' => :'speed', @@ -77,6 +89,9 @@ def self.openapi_types { :'type' => :'String', :'src' => :'String', + :'prompt' => :'String', + :'model' => :'String', + :'options' => :'Hash', :'trim' => :'Float', :'volume' => :'AudioAssetVolume', :'speed' => :'Float', @@ -113,8 +128,20 @@ def initialize(attributes = {}) if attributes.key?(:'src') self.src = attributes[:'src'] - else - self.src = nil + end + + if attributes.key?(:'prompt') + self.prompt = attributes[:'prompt'] + end + + if attributes.key?(:'model') + self.model = attributes[:'model'] + end + + if attributes.key?(:'options') + if (value = attributes[:'options']).is_a?(Hash) + self.options = value + end end if attributes.key?(:'trim') @@ -143,19 +170,19 @@ def list_invalid_properties invalid_properties.push('invalid value for "type", type cannot be nil.') end - if @src.nil? - invalid_properties.push('invalid value for "src", src cannot be nil.') - end - - if @src.to_s.length < 1 + if !@src.nil? && @src.to_s.length < 1 invalid_properties.push('invalid value for "src", the character length must be great than or equal to 1.') end pattern = Regexp.new(/\S/) - if @src !~ pattern + if !@src.nil? && @src !~ pattern invalid_properties.push("invalid value for \"src\", must conform to the pattern #{pattern}.") end + if !@prompt.nil? && @prompt.to_s.length > 4000 + invalid_properties.push('invalid value for "prompt", the character length must be smaller than or equal to 4000.') + end + if !@speed.nil? && @speed > 10 invalid_properties.push('invalid value for "speed", must be smaller than or equal to 10.') end @@ -174,9 +201,9 @@ def valid? return false if @type.nil? type_validator = EnumAttributeValidator.new('String', ["audio"]) return false unless type_validator.valid?(@type) - return false if @src.nil? - return false if @src.to_s.length < 1 - return false if @src !~ Regexp.new(/\S/) + return false if !@src.nil? && @src.to_s.length < 1 + return false if !@src.nil? && @src !~ Regexp.new(/\S/) + return false if !@prompt.nil? && @prompt.to_s.length > 4000 return false if !@speed.nil? && @speed > 10 return false if !@speed.nil? && @speed < 0 effect_validator = EnumAttributeValidator.new('String', ["none", "fadeIn", "fadeOut", "fadeInFadeOut"]) @@ -213,6 +240,20 @@ def src=(src) @src = src end + # Custom attribute writer method with validation + # @param [Object] prompt Value to be assigned + def prompt=(prompt) + if prompt.nil? + fail ArgumentError, 'prompt cannot be nil' + end + + if prompt.to_s.length > 4000 + fail ArgumentError, 'invalid value for "prompt", the character length must be smaller than or equal to 4000.' + end + + @prompt = prompt + end + # Custom attribute writer method with validation # @param [Object] speed Value to be assigned def speed=(speed) @@ -248,6 +289,9 @@ def ==(o) self.class == o.class && type == o.type && src == o.src && + prompt == o.prompt && + model == o.model && + options == o.options && trim == o.trim && volume == o.volume && speed == o.speed && @@ -263,7 +307,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [type, src, trim, volume, speed, effect].hash + [type, src, prompt, model, options, trim, volume, speed, effect].hash end # Builds the object from hash diff --git a/lib/shotstack/models/clip.rb b/lib/shotstack/models/clip.rb index c38a91d..d6c61b6 100644 --- a/lib/shotstack/models/clip.rb +++ b/lib/shotstack/models/clip.rb @@ -16,6 +16,9 @@ module Shotstack # A clip is a container for a specific type of asset, i.e. a title, image, video, audio or html. You use a Clip to define when an asset will display on the timeline, how long it will play for and transitions, filters and effects to apply to it. class Clip + # Optional client-generated identifier. Used by client SDKs (e.g. the Shotstack Studio SDK) to reference a clip across edits without relying on its position in the timeline. The render API does not use this field and it does not appear in render output. + attr_accessor :id + attr_accessor :asset attr_accessor :start @@ -78,6 +81,7 @@ def valid?(value) # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { + :'id' => :'id', :'asset' => :'asset', :'start' => :'start', :'length' => :'length', @@ -104,6 +108,7 @@ def self.acceptable_attributes # Attribute type mapping. def self.openapi_types { + :'id' => :'String', :'asset' => :'Asset', :'start' => :'ClipStart', :'length' => :'ClipLength', @@ -143,6 +148,10 @@ def initialize(attributes = {}) h[k.to_sym] = v } + if attributes.key?(:'id') + self.id = attributes[:'id'] + end + if attributes.key?(:'asset') self.asset = attributes[:'asset'] else @@ -370,6 +379,7 @@ def _alias=(_alias) def ==(o) return true if self.equal?(o) self.class == o.class && + id == o.id && asset == o.asset && start == o.start && length == o.length && @@ -396,7 +406,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [asset, start, length, fit, scale, width, height, position, offset, transition, effect, filter, opacity, transform, _alias].hash + [id, asset, start, length, fit, scale, width, height, position, offset, transition, effect, filter, opacity, transform, _alias].hash end # Builds the object from hash diff --git a/lib/shotstack/models/google_drive_destination.rb b/lib/shotstack/models/google_drive_destination.rb index e93a37b..80be255 100644 --- a/lib/shotstack/models/google_drive_destination.rb +++ b/lib/shotstack/models/google_drive_destination.rb @@ -71,8 +71,6 @@ def initialize(attributes = {}) if attributes.key?(:'options') self.options = attributes[:'options'] - else - self.options = nil end end @@ -85,10 +83,6 @@ def list_invalid_properties invalid_properties.push('invalid value for "provider", provider cannot be nil.') end - if @options.nil? - invalid_properties.push('invalid value for "options", options cannot be nil.') - end - invalid_properties end @@ -97,7 +91,6 @@ def list_invalid_properties def valid? warn '[DEPRECATED] the `valid?` method is obsolete' return false if @provider.nil? - return false if @options.nil? true end diff --git a/lib/shotstack/models/google_drive_destination_options.rb b/lib/shotstack/models/google_drive_destination_options.rb index 44c20ba..f6af8a9 100644 --- a/lib/shotstack/models/google_drive_destination_options.rb +++ b/lib/shotstack/models/google_drive_destination_options.rb @@ -16,7 +16,7 @@ module Shotstack # Pass the folder ID and options to configure how assets are stored in Google Drive. class GoogleDriveDestinationOptions - # The Google Drive folder ID where asset will be stored. The folder ID is required and can be retrieved from the URL when logged in to Google Drive, e.g. https://drive.google.com/drive/u/0/folders/1r-eTY6OLO8tzQRKwMyq-fIrQ_7AJEI6A. + # The Google Drive folder ID where the asset will be stored. If omitted, the asset is saved to the root of My Drive. The folder ID can be retrieved from the URL when logged in to Google Drive, e.g. https://drive.google.com/drive/u/0/folders/1r-eTY6OLO8tzQRKwMyq-fIrQ_7AJEI6A. attr_accessor :folder_id # Use your own filename instead of the default filenames generated by Shotstack. Note: omit the file extension as this will be appended depending on the output format. Also `-poster.jpg` and `-thumb.jpg` will be appended for poster and thumbnail images. @@ -66,8 +66,6 @@ def initialize(attributes = {}) if attributes.key?(:'folder_id') self.folder_id = attributes[:'folder_id'] - else - self.folder_id = nil end if attributes.key?(:'filename') @@ -80,10 +78,6 @@ def initialize(attributes = {}) def list_invalid_properties warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' invalid_properties = Array.new - if @folder_id.nil? - invalid_properties.push('invalid value for "folder_id", folder_id cannot be nil.') - end - invalid_properties end @@ -91,7 +85,6 @@ def list_invalid_properties # @return true if the model is valid def valid? warn '[DEPRECATED] the `valid?` method is obsolete' - return false if @folder_id.nil? true end diff --git a/lib/shotstack/models/html5_asset.rb b/lib/shotstack/models/html5_asset.rb new file mode 100644 index 0000000..0b15552 --- /dev/null +++ b/lib/shotstack/models/html5_asset.rb @@ -0,0 +1,351 @@ +=begin +#Shotstack + +# Official Ruby SDK for the Shotstack Cloud Video Editing API + +The version of the OpenAPI document: v1 + +Generated by: https://openapi-generator.tech +Generator version: 7.4.0 + +=end + +require 'date' +require 'time' + +module Shotstack + # The Html5Asset renders full HTML5/CSS3/JS. + class Html5Asset + # The type of asset - set to `html5` for HTML5/CSS3/JS. + attr_accessor :type + + # The HTML markup for the asset. Max 1,000,000 characters. + attr_accessor :html + + # The CSS string applied to the HTML. Max 500,000 characters. + attr_accessor :css + + # Optional JavaScript. Use for chart libraries, animations, or DOM manipulation. `gsap`, `d3`, `anime` and `lottie` are always available. CSS animations, transitions, and `Element.animate()` are also captured automatically. Max 500,000 characters. + attr_accessor :js + + class EnumAttributeValidator + attr_reader :datatype + attr_reader :allowable_values + + def initialize(datatype, allowable_values) + @allowable_values = allowable_values.map do |value| + case datatype.to_s + when /Integer/i + value.to_i + when /Float/i + value.to_f + else + value + end + end + end + + def valid?(value) + !value || allowable_values.include?(value) + end + end + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'type' => :'type', + :'html' => :'html', + :'css' => :'css', + :'js' => :'js' + } + end + + # Returns all the JSON keys this model knows about + def self.acceptable_attributes + attribute_map.values + end + + # Attribute type mapping. + def self.openapi_types + { + :'type' => :'String', + :'html' => :'String', + :'css' => :'String', + :'js' => :'String' + } + end + + # List of attributes with nullable: true + def self.openapi_nullable + Set.new([ + ]) + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `Shotstack::Html5Asset` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `Shotstack::Html5Asset`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'type') + self.type = attributes[:'type'] + else + self.type = 'html5' + end + + if attributes.key?(:'html') + self.html = attributes[:'html'] + else + self.html = nil + end + + if attributes.key?(:'css') + self.css = attributes[:'css'] + end + + if attributes.key?(:'js') + self.js = attributes[:'js'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @type.nil? + invalid_properties.push('invalid value for "type", type cannot be nil.') + end + + if @html.nil? + invalid_properties.push('invalid value for "html", html cannot be nil.') + end + + if @html.to_s.length > 1000000 + invalid_properties.push('invalid value for "html", the character length must be smaller than or equal to 1000000.') + end + + if !@css.nil? && @css.to_s.length > 500000 + invalid_properties.push('invalid value for "css", the character length must be smaller than or equal to 500000.') + end + + if !@js.nil? && @js.to_s.length > 500000 + invalid_properties.push('invalid value for "js", the character length must be smaller than or equal to 500000.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @type.nil? + type_validator = EnumAttributeValidator.new('String', ["html5"]) + return false unless type_validator.valid?(@type) + return false if @html.nil? + return false if @html.to_s.length > 1000000 + return false if !@css.nil? && @css.to_s.length > 500000 + return false if !@js.nil? && @js.to_s.length > 500000 + true + end + + # Custom attribute writer method checking allowed values (enum). + # @param [Object] type Object to be assigned + def type=(type) + validator = EnumAttributeValidator.new('String', ["html5"]) + unless validator.valid?(type) + fail ArgumentError, "invalid value for \"type\", must be one of #{validator.allowable_values}." + end + @type = type + end + + # Custom attribute writer method with validation + # @param [Object] html Value to be assigned + def html=(html) + if html.nil? + fail ArgumentError, 'html cannot be nil' + end + + if html.to_s.length > 1000000 + fail ArgumentError, 'invalid value for "html", the character length must be smaller than or equal to 1000000.' + end + + @html = html + end + + # Custom attribute writer method with validation + # @param [Object] css Value to be assigned + def css=(css) + if css.nil? + fail ArgumentError, 'css cannot be nil' + end + + if css.to_s.length > 500000 + fail ArgumentError, 'invalid value for "css", the character length must be smaller than or equal to 500000.' + end + + @css = css + end + + # Custom attribute writer method with validation + # @param [Object] js Value to be assigned + def js=(js) + if js.nil? + fail ArgumentError, 'js cannot be nil' + end + + if js.to_s.length > 500000 + fail ArgumentError, 'invalid value for "js", the character length must be smaller than or equal to 500000.' + end + + @js = js + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + type == o.type && + html == o.html && + css == o.css && + js == o.js + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Integer] Hash code + def hash + [type, html, css, js].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + attributes = attributes.transform_keys(&:to_sym) + transformed_hash = {} + openapi_types.each_pair do |key, type| + if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = nil + elsif type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[attribute_map[key]].is_a?(Array) + transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) } + end + elsif !attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]]) + end + end + new(transformed_hash) + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def self._deserialize(type, value) + case type.to_sym + when :Time + Time.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + # models (e.g. Pet) or oneOf + klass = Shotstack.const_get(type) + klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + if value.nil? + is_nullable = self.class.openapi_nullable.include?(attr) + next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}")) + end + + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/lib/shotstack/models/html_asset.rb b/lib/shotstack/models/html_asset.rb index 3f55e14..2f85ca2 100644 --- a/lib/shotstack/models/html_asset.rb +++ b/lib/shotstack/models/html_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # **Notice: The HtmlAsset is deprecated, use the [TextAsset](#tocs_textasset) instead.** The HtmlAsset clip type lets you create text based layout and formatting using HTML and CSS. You can also set the height and width of a bounding box for the HTML content to sit within. Text and elements will wrap within the bounding box. + # **Notice: The HtmlAsset is deprecated, use the [RichTextAsset](#tocs_richtextasset) instead.** The HtmlAsset clip type lets you create text based layout and formatting using HTML and CSS. You can also set the height and width of a bounding box for the HTML content to sit within. Text and elements will wrap within the bounding box. class HtmlAsset # The type of asset - set to `html` for HTML. attr_accessor :type diff --git a/lib/shotstack/models/image_asset.rb b/lib/shotstack/models/image_asset.rb index 19deda4..89a7165 100644 --- a/lib/shotstack/models/image_asset.rb +++ b/lib/shotstack/models/image_asset.rb @@ -14,14 +14,23 @@ require 'time' module Shotstack - # The ImageAsset is used to create video from images to compose an image. The src must be a publicly accessible URL to an image resource such as a jpg or png file. + # The ImageAsset adds an image to a Clip. The image can be sourced from a URL (`src`), generated from a text prompt (`prompt`), or both. At least one of `src` or `prompt` must be provided. - **Source URL:** set `src` to the publicly accessible URL of a jpg or png file. - **Generated:** set `prompt` to describe the image. Choose a generator with `model` and configure it with model-specific `options`; the engine fills `src` in automatically. - **Both:** `src` acts as a preview placeholder while `prompt` drives generation — the image is regenerated from the prompt at render time. Unchanged prompts and options resolve from the generation cache. class ImageAsset # The type of asset - set to `image` for images. attr_accessor :type - # The image source URL. The URL must be publicly accessible or include credentials. + # The image source URL. The URL must be publicly accessible or include credentials. When `prompt` is also set, `src` serves as a preview placeholder and the image is regenerated from the prompt at render time. attr_accessor :src + # A text prompt to generate the image from. The engine generates an image at render time and fills `src` automatically; an existing `src` is treated as a preview placeholder and replaced. Use `model` to choose the generator and `options` to configure it. + attr_accessor :prompt + + # The generation model to use when `prompt` is set (e.g. `flux-schnell`, `nano-banana-2`). Defaults to `nano-banana-2` if omitted. Each model's available options are defined by the model registry. + attr_accessor :model + + # Model-specific generation settings. Valid keys and values depend on the chosen `model` and are defined by the model registry. Omitted options use the model's defaults. Unknown or invalid options are rejected. + attr_accessor :options + attr_accessor :crop class EnumAttributeValidator @@ -51,6 +60,9 @@ def self.attribute_map { :'type' => :'type', :'src' => :'src', + :'prompt' => :'prompt', + :'model' => :'model', + :'options' => :'options', :'crop' => :'crop' } end @@ -65,6 +77,9 @@ def self.openapi_types { :'type' => :'String', :'src' => :'String', + :'prompt' => :'String', + :'model' => :'String', + :'options' => :'Hash', :'crop' => :'Crop' } end @@ -98,8 +113,20 @@ def initialize(attributes = {}) if attributes.key?(:'src') self.src = attributes[:'src'] - else - self.src = nil + end + + if attributes.key?(:'prompt') + self.prompt = attributes[:'prompt'] + end + + if attributes.key?(:'model') + self.model = attributes[:'model'] + end + + if attributes.key?(:'options') + if (value = attributes[:'options']).is_a?(Hash) + self.options = value + end end if attributes.key?(:'crop') @@ -116,19 +143,19 @@ def list_invalid_properties invalid_properties.push('invalid value for "type", type cannot be nil.') end - if @src.nil? - invalid_properties.push('invalid value for "src", src cannot be nil.') - end - - if @src.to_s.length < 1 + if !@src.nil? && @src.to_s.length < 1 invalid_properties.push('invalid value for "src", the character length must be great than or equal to 1.') end pattern = Regexp.new(/\S/) - if @src !~ pattern + if !@src.nil? && @src !~ pattern invalid_properties.push("invalid value for \"src\", must conform to the pattern #{pattern}.") end + if !@prompt.nil? && @prompt.to_s.length > 4000 + invalid_properties.push('invalid value for "prompt", the character length must be smaller than or equal to 4000.') + end + invalid_properties end @@ -139,9 +166,9 @@ def valid? return false if @type.nil? type_validator = EnumAttributeValidator.new('String', ["image"]) return false unless type_validator.valid?(@type) - return false if @src.nil? - return false if @src.to_s.length < 1 - return false if @src !~ Regexp.new(/\S/) + return false if !@src.nil? && @src.to_s.length < 1 + return false if !@src.nil? && @src !~ Regexp.new(/\S/) + return false if !@prompt.nil? && @prompt.to_s.length > 4000 true end @@ -174,6 +201,20 @@ def src=(src) @src = src end + # Custom attribute writer method with validation + # @param [Object] prompt Value to be assigned + def prompt=(prompt) + if prompt.nil? + fail ArgumentError, 'prompt cannot be nil' + end + + if prompt.to_s.length > 4000 + fail ArgumentError, 'invalid value for "prompt", the character length must be smaller than or equal to 4000.' + end + + @prompt = prompt + end + # Checks equality by comparing each attribute. # @param [Object] Object to be compared def ==(o) @@ -181,6 +222,9 @@ def ==(o) self.class == o.class && type == o.type && src == o.src && + prompt == o.prompt && + model == o.model && + options == o.options && crop == o.crop end @@ -193,7 +237,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [type, src, crop].hash + [type, src, prompt, model, options, crop].hash end # Builds the object from hash diff --git a/lib/shotstack/models/image_to_video_asset.rb b/lib/shotstack/models/image_to_video_asset.rb index fa91682..d14a908 100644 --- a/lib/shotstack/models/image_to_video_asset.rb +++ b/lib/shotstack/models/image_to_video_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # The ImageToVideoAsset lets you create a video from an image and a text prompt. + # **Notice: ImageToVideoAsset is deprecated. Use [VideoAsset](#tocs_videoasset) with `prompt` and `inputSrc` instead.** This type continues to function and is internally rewritten to VideoAsset; no behaviour change for existing integrations. The ImageToVideoAsset lets you create a video from an image and a text prompt. class ImageToVideoAsset # The type of asset to generate - set to `image-to-video` for image-to-video. attr_accessor :type diff --git a/lib/shotstack/models/output.rb b/lib/shotstack/models/output.rb index cf47d09..5a03fba 100644 --- a/lib/shotstack/models/output.rb +++ b/lib/shotstack/models/output.rb @@ -14,12 +14,12 @@ require 'time' module Shotstack - # The output format, render range and type of media to generate. + # The output format, render range and type of media to generate. For all formats except `mp3`, either `resolution` or `size` (with both `width` and `height`) must be specified. class Output # The output format and type of media file to generate.
  • `mp4` - mp4 video file
  • `gif` - animated gif
  • `jpg` - jpg image file
  • `png` - png image file
  • `bmp` - bmp image file
  • `mp3` - mp3 audio file (audio only)
attr_accessor :format - # The preset output resolution of the video or image. For custom sizes use the `size` property.
  • `preview` - 512px x 288px @ 15fps
  • `mobile` - 640px x 360px @ 25fps
  • `sd` - 1024px x 576px @ 25fps
  • `hd` - 1280px x 720px @ 25fps
  • `1080` - 1920px x 1080px @ 25fps
  • `4k` - 3840px x 2160px @ 25fps
+ # The preset output resolution of the video or image. For custom sizes use the `size` property. Either `resolution` or `size` (with both `width` and `height`) must be specified for all formats except `mp3`.
  • `preview` - 512px x 288px @ 15fps
  • `mobile` - 640px x 360px @ 25fps
  • `sd` - 1024px x 576px @ 25fps
  • `hd` - 1280px x 720px @ 25fps
  • `1080` - 1920px x 1080px @ 25fps
  • `4k` - 3840px x 2160px @ 25fps
attr_accessor :resolution # The aspect ratio (shape) of the video or image. Useful for social media output formats. Options are:
  • `16:9` (default) - regular landscape/horizontal aspect ratio
  • `9:16` - vertical/portrait aspect ratio
  • `1:1` - square aspect ratio
  • `4:5` - short vertical/portrait aspect ratio
  • `4:3` - legacy TV aspect ratio
diff --git a/lib/shotstack/models/post_generate200_response.rb b/lib/shotstack/models/post_generate200_response.rb new file mode 100644 index 0000000..10dab62 --- /dev/null +++ b/lib/shotstack/models/post_generate200_response.rb @@ -0,0 +1,294 @@ +=begin +#Shotstack + +# Official Ruby SDK for the Shotstack Cloud Video Editing API + +The version of the OpenAPI document: v1 + +Generated by: https://openapi-generator.tech +Generator version: 7.4.0 + +=end + +require 'date' +require 'time' + +module Shotstack + # The status of an on-demand asset generation job. Completed jobs include the public URL of the generated asset. + class PostGenerate200Response + # The generation job id. Deterministic for a given owner and asset payload (or idempotency key), so identical requests return the same job and cached result. + attr_accessor :id + + # The status of the generation job. + attr_accessor :status + + # The public URL of the generated asset. Present only when `status` is `done`. + attr_accessor :url + + # A human readable error message. Present only when `status` is `failed`. + attr_accessor :error + + class EnumAttributeValidator + attr_reader :datatype + attr_reader :allowable_values + + def initialize(datatype, allowable_values) + @allowable_values = allowable_values.map do |value| + case datatype.to_s + when /Integer/i + value.to_i + when /Float/i + value.to_f + else + value + end + end + end + + def valid?(value) + !value || allowable_values.include?(value) + end + end + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'id' => :'id', + :'status' => :'status', + :'url' => :'url', + :'error' => :'error' + } + end + + # Returns all the JSON keys this model knows about + def self.acceptable_attributes + attribute_map.values + end + + # Attribute type mapping. + def self.openapi_types + { + :'id' => :'String', + :'status' => :'String', + :'url' => :'String', + :'error' => :'String' + } + end + + # List of attributes with nullable: true + def self.openapi_nullable + Set.new([ + ]) + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `Shotstack::PostGenerate200Response` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `Shotstack::PostGenerate200Response`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'id') + self.id = attributes[:'id'] + else + self.id = nil + end + + if attributes.key?(:'status') + self.status = attributes[:'status'] + else + self.status = nil + end + + if attributes.key?(:'url') + self.url = attributes[:'url'] + end + + if attributes.key?(:'error') + self.error = attributes[:'error'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @id.nil? + invalid_properties.push('invalid value for "id", id cannot be nil.') + end + + if @status.nil? + invalid_properties.push('invalid value for "status", status cannot be nil.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @id.nil? + return false if @status.nil? + status_validator = EnumAttributeValidator.new('String', ["queued", "processing", "done", "failed"]) + return false unless status_validator.valid?(@status) + true + end + + # Custom attribute writer method checking allowed values (enum). + # @param [Object] status Object to be assigned + def status=(status) + validator = EnumAttributeValidator.new('String', ["queued", "processing", "done", "failed"]) + unless validator.valid?(status) + fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}." + end + @status = status + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + id == o.id && + status == o.status && + url == o.url && + error == o.error + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Integer] Hash code + def hash + [id, status, url, error].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + attributes = attributes.transform_keys(&:to_sym) + transformed_hash = {} + openapi_types.each_pair do |key, type| + if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = nil + elsif type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[attribute_map[key]].is_a?(Array) + transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) } + end + elsif !attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]]) + end + end + new(transformed_hash) + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def self._deserialize(type, value) + case type.to_sym + when :Time + Time.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + # models (e.g. Pet) or oneOf + klass = Shotstack.const_get(type) + klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + if value.nil? + is_nullable = self.class.openapi_nullable.include?(attr) + next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}")) + end + + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/lib/shotstack/models/post_generate_request.rb b/lib/shotstack/models/post_generate_request.rb new file mode 100644 index 0000000..17fee35 --- /dev/null +++ b/lib/shotstack/models/post_generate_request.rb @@ -0,0 +1,221 @@ +=begin +#Shotstack + +# Official Ruby SDK for the Shotstack Cloud Video Editing API + +The version of the OpenAPI document: v1 + +Generated by: https://openapi-generator.tech +Generator version: 7.4.0 + +=end + +require 'date' +require 'time' + +module Shotstack + class PostGenerateRequest + attr_accessor :asset + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'asset' => :'asset' + } + end + + # Returns all the JSON keys this model knows about + def self.acceptable_attributes + attribute_map.values + end + + # Attribute type mapping. + def self.openapi_types + { + :'asset' => :'PostGenerateRequestAsset' + } + end + + # List of attributes with nullable: true + def self.openapi_nullable + Set.new([ + ]) + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `Shotstack::PostGenerateRequest` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `Shotstack::PostGenerateRequest`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'asset') + self.asset = attributes[:'asset'] + else + self.asset = nil + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + warn '[DEPRECATED] the `list_invalid_properties` method is obsolete' + invalid_properties = Array.new + if @asset.nil? + invalid_properties.push('invalid value for "asset", asset cannot be nil.') + end + + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + warn '[DEPRECATED] the `valid?` method is obsolete' + return false if @asset.nil? + true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + asset == o.asset + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Integer] Hash code + def hash + [asset].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + attributes = attributes.transform_keys(&:to_sym) + transformed_hash = {} + openapi_types.each_pair do |key, type| + if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = nil + elsif type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[attribute_map[key]].is_a?(Array) + transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) } + end + elsif !attributes[attribute_map[key]].nil? + transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]]) + end + end + new(transformed_hash) + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def self._deserialize(type, value) + case type.to_sym + when :Time + Time.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + # models (e.g. Pet) or oneOf + klass = Shotstack.const_get(type) + klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + if value.nil? + is_nullable = self.class.openapi_nullable.include?(attr) + next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}")) + end + + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/lib/shotstack/models/post_generate_request_asset.rb b/lib/shotstack/models/post_generate_request_asset.rb new file mode 100644 index 0000000..4c7c12c --- /dev/null +++ b/lib/shotstack/models/post_generate_request_asset.rb @@ -0,0 +1,106 @@ +=begin +#Shotstack + +# Official Ruby SDK for the Shotstack Cloud Video Editing API + +The version of the OpenAPI document: v1 + +Generated by: https://openapi-generator.tech +Generator version: 7.4.0 + +=end + +require 'date' +require 'time' + +module Shotstack + module PostGenerateRequestAsset + class << self + # List of class defined in oneOf (OpenAPI v3) + def openapi_one_of + [ + :'AudioAsset', + :'ImageAsset', + :'VideoAsset' + ] + end + + # Builds the object + # @param [Mixed] Data to be matched against the list of oneOf items + # @return [Object] Returns the model or the data itself + def build(data) + # Go through the list of oneOf items and attempt to identify the appropriate one. + # Note: + # - We do not attempt to check whether exactly one item matches. + # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 }) + # due to the way the deserialization is made in the base_object template (it just casts without verifying). + # - TODO: scalar values are de facto behaving as if they were nullable. + # - TODO: logging when debugging is set. + openapi_one_of.each do |klass| + begin + next if klass == :AnyType # "nullable: true" + typed_data = find_and_cast_into_type(klass, data) + return typed_data if typed_data + rescue # rescue all errors so we keep iterating even if the current item lookup raises + end + end + + openapi_one_of.include?(:AnyType) ? data : nil + end + + private + + SchemaMismatchError = Class.new(StandardError) + + # Note: 'File' is missing here because in the regular case we get the data _after_ a call to JSON.parse. + def find_and_cast_into_type(klass, data) + return if data.nil? + + case klass.to_s + when 'Boolean' + return data if data.instance_of?(TrueClass) || data.instance_of?(FalseClass) + when 'Float' + return data if data.instance_of?(Float) + when 'Integer' + return data if data.instance_of?(Integer) + when 'Time' + return Time.parse(data) + when 'Date' + return Date.parse(data) + when 'String' + return data if data.instance_of?(String) + when 'Object' # "type: object" + return data if data.instance_of?(Hash) + when /\AArray<(?.+)>\z/ # "type: array" + if data.instance_of?(Array) + sub_type = Regexp.last_match[:sub_type] + return data.map { |item| find_and_cast_into_type(sub_type, item) } + end + when /\AHash.+)>\z/ # "type: object" with "additionalProperties: { ... }" + if data.instance_of?(Hash) && data.keys.all? { |k| k.instance_of?(Symbol) || k.instance_of?(String) } + sub_type = Regexp.last_match[:sub_type] + return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) } + end + else # model + const = Shotstack.const_get(klass) + if const + if const.respond_to?(:openapi_one_of) # nested oneOf model + model = const.build(data) + return model if model + else + # raise if data contains keys that are not known to the model + raise if const.respond_to?(:acceptable_attributes) && !(data.keys - const.acceptable_attributes).empty? + model = const.build_from_hash(data) + return model if model + end + end + end + + raise # if no match by now, raise + rescue + raise SchemaMismatchError, "#{data} doesn't match the #{klass} type" + end + end + end + +end diff --git a/lib/shotstack/models/rich_caption_asset.rb b/lib/shotstack/models/rich_caption_asset.rb index b1adfb8..6f97c08 100644 --- a/lib/shotstack/models/rich_caption_asset.rb +++ b/lib/shotstack/models/rich_caption_asset.rb @@ -14,12 +14,12 @@ require 'time' module Shotstack - # The RichCaptionAsset provides word-level caption animations with rich-text styling. It supports karaoke-style highlighting, word-by-word animations, and advanced typography. Use with SRT/VTT files or auto-transcription via aliases. + # The RichCaptionAsset provides word-level caption animations with rich-text styling. It supports karaoke-style highlighting, word-by-word animations, and advanced typography. Captions can be sourced from SRT/VTT/TTML subtitle files, from audio/video media URLs (auto-transcribed), or from alias references to other clips in the same timeline. class RichCaptionAsset # The type of asset - set to `rich-caption` for rich captions. attr_accessor :type - # The URL to an SRT or VTT subtitles file, or an alias reference to auto-generate captions from an audio or video clip. For file URLs, the URL must be publicly accessible or include credentials. For auto-captioning, use the format `alias://clip-name` where clip-name is the alias of an audio, video, or text-to-speech clip. + # Source for the caption words. Accepts three formats: (1) the URL to a subtitle file (`.srt`, `.vtt`, `.ttml`, or `.dfxp`) which is parsed directly; (2) the URL to an audio or video media file (`.mp4`, `.mov`, `.webm`, `.mp3`, `.wav`, `.m4a`, `.flac`, `.aac`, `.ogg`, and related formats) which is auto-transcribed; (3) an alias reference in the form `alias://clip-name` where `clip-name` is the alias of another audio, video, or text-to-speech clip in the same timeline — the referenced clip's source is auto-transcribed. For file URLs, the URL must be publicly accessible or include credentials. Content is classified at runtime and unsupported content types (HTML, PDF, images, archives) are rejected with a structured error. attr_accessor :src attr_accessor :font diff --git a/lib/shotstack/models/rich_text_background.rb b/lib/shotstack/models/rich_text_background.rb index 1df053c..b781a39 100644 --- a/lib/shotstack/models/rich_text_background.rb +++ b/lib/shotstack/models/rich_text_background.rb @@ -25,12 +25,20 @@ class RichTextBackground # The border radius of the background box in pixels. Must be 0 or greater. attr_accessor :border_radius + # When true, the background pill shrinks to fit the rendered text bounding box plus the asset's padding (and stroke width, if present), producing a pill or badge effect. When false (default), the background fills the full asset content area. Available on rich-text and rich-caption assets only; not supported on legacy `type: text`. + attr_accessor :wrap + + # Inner padding in pixels between the wrap pill edge and the rendered text. Only takes effect when `wrap: true`. When omitted, the renderer applies a sensible default proportional to the font size (approximately 12% of the active page font size on rich-caption assets). Set to 0 for a pill that hugs the text exactly. Available on rich-text and rich-caption assets only. + attr_accessor :padding + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { :'color' => :'color', :'opacity' => :'opacity', - :'border_radius' => :'borderRadius' + :'border_radius' => :'borderRadius', + :'wrap' => :'wrap', + :'padding' => :'padding' } end @@ -44,7 +52,9 @@ def self.openapi_types { :'color' => :'String', :'opacity' => :'Float', - :'border_radius' => :'Float' + :'border_radius' => :'Float', + :'wrap' => :'Boolean', + :'padding' => :'Integer' } end @@ -84,6 +94,16 @@ def initialize(attributes = {}) else self.border_radius = 0 end + + if attributes.key?(:'wrap') + self.wrap = attributes[:'wrap'] + else + self.wrap = false + end + + if attributes.key?(:'padding') + self.padding = attributes[:'padding'] + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -108,6 +128,14 @@ def list_invalid_properties invalid_properties.push('invalid value for "border_radius", must be greater than or equal to 0.') end + if !@padding.nil? && @padding > 200 + invalid_properties.push('invalid value for "padding", must be smaller than or equal to 200.') + end + + if !@padding.nil? && @padding < 0 + invalid_properties.push('invalid value for "padding", must be greater than or equal to 0.') + end + invalid_properties end @@ -119,6 +147,8 @@ def valid? return false if !@opacity.nil? && @opacity > 1 return false if !@opacity.nil? && @opacity < 0 return false if !@border_radius.nil? && @border_radius < 0 + return false if !@padding.nil? && @padding > 200 + return false if !@padding.nil? && @padding < 0 true end @@ -169,6 +199,24 @@ def border_radius=(border_radius) @border_radius = border_radius end + # Custom attribute writer method with validation + # @param [Object] padding Value to be assigned + def padding=(padding) + if padding.nil? + fail ArgumentError, 'padding cannot be nil' + end + + if padding > 200 + fail ArgumentError, 'invalid value for "padding", must be smaller than or equal to 200.' + end + + if padding < 0 + fail ArgumentError, 'invalid value for "padding", must be greater than or equal to 0.' + end + + @padding = padding + end + # Checks equality by comparing each attribute. # @param [Object] Object to be compared def ==(o) @@ -176,7 +224,9 @@ def ==(o) self.class == o.class && color == o.color && opacity == o.opacity && - border_radius == o.border_radius + border_radius == o.border_radius && + wrap == o.wrap && + padding == o.padding end # @see the `==` method @@ -188,7 +238,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [color, opacity, border_radius].hash + [color, opacity, border_radius, wrap, padding].hash end # Builds the object from hash diff --git a/lib/shotstack/models/soundtrack.rb b/lib/shotstack/models/soundtrack.rb index 7e63b9f..e5a9f51 100644 --- a/lib/shotstack/models/soundtrack.rb +++ b/lib/shotstack/models/soundtrack.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # A music or audio file in mp3 format that plays for the duration of the rendered video or the length of the audio file, which ever is shortest. + # **Notice: The Soundtrack is deprecated, use an [AudioAsset](#tocs_audioasset) clip on its own track instead.** This type continues to function; no behaviour change for existing integrations. A music or audio file in mp3 format that plays for the duration of the rendered video or the length of the audio file, which ever is shortest. class Soundtrack # The URL of the mp3 audio file. The URL must be publicly accessible or include credentials. attr_accessor :src diff --git a/lib/shotstack/models/text_asset.rb b/lib/shotstack/models/text_asset.rb index d36ef72..473d3d5 100644 --- a/lib/shotstack/models/text_asset.rb +++ b/lib/shotstack/models/text_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # The TextAsset is used to add text and titles to a video. The text can be styled with built in and custom [Fonts](#tocs_font). You can also add a background bounding box used to control wrapping and overflow. Emoticons are also supported. + # **Notice: The TextAsset is deprecated, use the [RichTextAsset](#tocs_richtextasset) instead.** This type continues to function; no behaviour change for existing integrations. The TextAsset is used to add text and titles to a video. The text can be styled with built in and custom [Fonts](#tocs_font). You can also add a background bounding box used to control wrapping and overflow. Emoticons are also supported. class TextAsset # The type of asset - set to `text` for text. attr_accessor :type diff --git a/lib/shotstack/models/text_background.rb b/lib/shotstack/models/text_background.rb index 375cf90..fba4c52 100644 --- a/lib/shotstack/models/text_background.rb +++ b/lib/shotstack/models/text_background.rb @@ -28,13 +28,17 @@ class TextBackground # The border radius of the background box in pixels for rounded corners. attr_accessor :border_radius + # Not supported on legacy `text` assets. Accepted here only so validators can emit a clear migration error pointing users to `rich-text` or `rich-caption`, which support background wrapping natively. + attr_accessor :wrap + # Attribute mapping from ruby-style variable name to JSON key. def self.attribute_map { :'color' => :'color', :'opacity' => :'opacity', :'padding' => :'padding', - :'border_radius' => :'borderRadius' + :'border_radius' => :'borderRadius', + :'wrap' => :'wrap' } end @@ -49,7 +53,8 @@ def self.openapi_types :'color' => :'String', :'opacity' => :'Float', :'padding' => :'Float', - :'border_radius' => :'Float' + :'border_radius' => :'Float', + :'wrap' => :'Boolean' } end @@ -89,6 +94,10 @@ def initialize(attributes = {}) if attributes.key?(:'border_radius') self.border_radius = attributes[:'border_radius'] end + + if attributes.key?(:'wrap') + self.wrap = attributes[:'wrap'] + end end # Show invalid properties with the reasons. Usually used together with valid? @@ -210,7 +219,8 @@ def ==(o) color == o.color && opacity == o.opacity && padding == o.padding && - border_radius == o.border_radius + border_radius == o.border_radius && + wrap == o.wrap end # @see the `==` method @@ -222,7 +232,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [color, opacity, padding, border_radius].hash + [color, opacity, padding, border_radius, wrap].hash end # Builds the object from hash diff --git a/lib/shotstack/models/text_to_image_asset.rb b/lib/shotstack/models/text_to_image_asset.rb index 1d91c36..bf3a772 100644 --- a/lib/shotstack/models/text_to_image_asset.rb +++ b/lib/shotstack/models/text_to_image_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # The TextToImageAsset lets you create a dynamic image from a text prompt. + # **Notice: TextToImageAsset is deprecated. Use [ImageAsset](#tocs_imageasset) with `prompt` instead.** This type continues to function and is internally rewritten to ImageAsset; no behaviour change for existing integrations. The TextToImageAsset lets you create a dynamic image from a text prompt. class TextToImageAsset # The type of asset to generate - set to `text-to-image` for text-to-image. attr_accessor :type diff --git a/lib/shotstack/models/text_to_speech_asset.rb b/lib/shotstack/models/text_to_speech_asset.rb index 35a2538..a2bc9b1 100644 --- a/lib/shotstack/models/text_to_speech_asset.rb +++ b/lib/shotstack/models/text_to_speech_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # The TextToSpeechAsset lets you generate a voice over from text using a text-to-speech service. The generated audio can be trimmed, faded and have its volume and speed adjusted using the same properties available on the AudioAsset. + # **Notice: TextToSpeechAsset is deprecated. Use [AudioAsset](#tocs_audioasset) with `prompt` (the spoken text) and `voice` instead.** This type continues to function and is internally rewritten to AudioAsset; no behaviour change for existing integrations. The TextToSpeechAsset lets you generate a voice over from text using a text-to-speech service. The generated audio can be trimmed, faded and have its volume and speed adjusted using the same properties available on the AudioAsset. class TextToSpeechAsset # The type of asset - set to `text-to-speech` for text-to-speech. attr_accessor :type diff --git a/lib/shotstack/models/title_asset.rb b/lib/shotstack/models/title_asset.rb index a16b1a5..38c10ad 100644 --- a/lib/shotstack/models/title_asset.rb +++ b/lib/shotstack/models/title_asset.rb @@ -14,7 +14,7 @@ require 'time' module Shotstack - # **Notice: The TitleAsset is deprecated, use the [TextAsset](#tocs_textasset) instead.** The TitleAsset clip type lets you create video titles from a text string and apply styling and positioning. + # **Notice: The TitleAsset is deprecated, use the [RichTextAsset](#tocs_richtextasset) instead.** The TitleAsset clip type lets you create video titles from a text string and apply styling and positioning. class TitleAsset # The type of asset - set to `title` for titles. attr_accessor :type diff --git a/lib/shotstack/models/video_asset.rb b/lib/shotstack/models/video_asset.rb index 529a66d..17ee6ca 100644 --- a/lib/shotstack/models/video_asset.rb +++ b/lib/shotstack/models/video_asset.rb @@ -14,14 +14,23 @@ require 'time' module Shotstack - # The VideoAsset is used to create video sequences from video files. The src must be a publicly accessible URL to a video resource such as an mp4 file. + # The VideoAsset adds a video to a Clip. The video can be sourced from a URL (`src`), generated from a text prompt (`prompt`), or both. At least one of `src` or `prompt` must be provided. - **Source URL:** set `src` to the URL of an mp4 (or compatible) video file. - **Generated:** set `prompt` to describe the motion. Choose a generator with `model` and configure it with model-specific `options` (including a starting image for image-to-video). The generated `src` is filled in automatically. - **Both:** `src` acts as a preview placeholder while `prompt` drives generation — the video is regenerated from the prompt at render time. Unchanged prompts and options resolve from the generation cache. class VideoAsset # The type of asset - set to `video` for videos. attr_accessor :type - # The video source URL. The URL must be publicly accessible or include credentials. + # The video source URL. The URL must be publicly accessible or include credentials. When `prompt` is also set, `src` serves as a preview placeholder and the video is regenerated from the prompt at render time. attr_accessor :src + # A text prompt to generate the video from. The engine generates a video at render time and fills `src` automatically; an existing `src` is treated as a preview placeholder and replaced. Use `model` to choose the generator and `options` to configure it (including a starting image for image-to-video). + attr_accessor :prompt + + # The generation model to use when `prompt` is set (e.g. `shotstack-itv-mini`, `ray-flash-2`, `seedance-2.0`). Defaults to `seedance-2.0` if omitted. Each model's available options are defined by the model registry. + attr_accessor :model + + # Model-specific generation settings. Valid keys and values depend on the chosen `model` and are defined by the model registry. Omitted options use the model's defaults. Unknown or invalid options are rejected. + attr_accessor :options + # Set to `true` to force re-encoding of the video during preprocessing. This can help resolve compatibility issues, fix rotation problems, synchronize audio, or convert formats. The video will be processed to ensure optimal compatibility with the rendering engine. attr_accessor :transcode @@ -33,7 +42,7 @@ class VideoAsset # Preset volume effects to apply to the video asset
  • `fadeIn` - fade volume in only
  • `fadeOut` - fade volume out only
  • `fadeInFadeOut` - fade volume in and out
attr_accessor :volume_effect - # Adjust the playback speed of the video clip between 0 (paused) and 10 (10x normal speed) where 1 is normal speed (defaults to 1). Adjusting the speed will also adjust the duration of the clip and may require you to adjust the Clip length. For example, if you set speed to 0.5, the clip will need to be 2x as long to play the entire video (i.e. original length / 0.5). If you set speed to 2, the clip will need to be half as long to play the entire video (i.e. original length / 2). + # Adjust the playback speed of the video clip between 0 (paused) and 10 (10x normal speed) where 1 is normal speed (defaults to 1). Adjusting the speed will also adjust the duration of the clip and may require you to adjust the Clip length. For example, if you set speed to 0.5, the clip will need to be 2x as long to play the entire video (i.e. original length / 0.5). If you set speed to 2, the clip will need to be half as long to play the entire video (i.e. original length / 2). attr_accessor :speed attr_accessor :crop @@ -67,6 +76,9 @@ def self.attribute_map { :'type' => :'type', :'src' => :'src', + :'prompt' => :'prompt', + :'model' => :'model', + :'options' => :'options', :'transcode' => :'transcode', :'trim' => :'trim', :'volume' => :'volume', @@ -87,6 +99,9 @@ def self.openapi_types { :'type' => :'String', :'src' => :'String', + :'prompt' => :'String', + :'model' => :'String', + :'options' => :'Hash', :'transcode' => :'Boolean', :'trim' => :'Float', :'volume' => :'VideoAssetVolume', @@ -126,8 +141,20 @@ def initialize(attributes = {}) if attributes.key?(:'src') self.src = attributes[:'src'] - else - self.src = nil + end + + if attributes.key?(:'prompt') + self.prompt = attributes[:'prompt'] + end + + if attributes.key?(:'model') + self.model = attributes[:'model'] + end + + if attributes.key?(:'options') + if (value = attributes[:'options']).is_a?(Hash) + self.options = value + end end if attributes.key?(:'transcode') @@ -168,19 +195,19 @@ def list_invalid_properties invalid_properties.push('invalid value for "type", type cannot be nil.') end - if @src.nil? - invalid_properties.push('invalid value for "src", src cannot be nil.') - end - - if @src.to_s.length < 1 + if !@src.nil? && @src.to_s.length < 1 invalid_properties.push('invalid value for "src", the character length must be great than or equal to 1.') end pattern = Regexp.new(/\S/) - if @src !~ pattern + if !@src.nil? && @src !~ pattern invalid_properties.push("invalid value for \"src\", must conform to the pattern #{pattern}.") end + if !@prompt.nil? && @prompt.to_s.length > 4000 + invalid_properties.push('invalid value for "prompt", the character length must be smaller than or equal to 4000.') + end + if !@speed.nil? && @speed > 10 invalid_properties.push('invalid value for "speed", must be smaller than or equal to 10.') end @@ -199,9 +226,9 @@ def valid? return false if @type.nil? type_validator = EnumAttributeValidator.new('String', ["video"]) return false unless type_validator.valid?(@type) - return false if @src.nil? - return false if @src.to_s.length < 1 - return false if @src !~ Regexp.new(/\S/) + return false if !@src.nil? && @src.to_s.length < 1 + return false if !@src.nil? && @src !~ Regexp.new(/\S/) + return false if !@prompt.nil? && @prompt.to_s.length > 4000 volume_effect_validator = EnumAttributeValidator.new('String', ["none", "fadeIn", "fadeOut", "fadeInFadeOut"]) return false unless volume_effect_validator.valid?(@volume_effect) return false if !@speed.nil? && @speed > 10 @@ -238,6 +265,20 @@ def src=(src) @src = src end + # Custom attribute writer method with validation + # @param [Object] prompt Value to be assigned + def prompt=(prompt) + if prompt.nil? + fail ArgumentError, 'prompt cannot be nil' + end + + if prompt.to_s.length > 4000 + fail ArgumentError, 'invalid value for "prompt", the character length must be smaller than or equal to 4000.' + end + + @prompt = prompt + end + # Custom attribute writer method checking allowed values (enum). # @param [Object] volume_effect Object to be assigned def volume_effect=(volume_effect) @@ -273,6 +314,9 @@ def ==(o) self.class == o.class && type == o.type && src == o.src && + prompt == o.prompt && + model == o.model && + options == o.options && transcode == o.transcode && trim == o.trim && volume == o.volume && @@ -291,7 +335,7 @@ def eql?(o) # Calculates hash code according to all attributes. # @return [Integer] Hash code def hash - [type, src, transcode, trim, volume, volume_effect, speed, crop, chroma_key].hash + [type, src, prompt, model, options, transcode, trim, volume, volume_effect, speed, crop, chroma_key].hash end # Builds the object from hash diff --git a/lib/shotstack/version.rb b/lib/shotstack/version.rb index 9dce678..93897f6 100644 --- a/lib/shotstack/version.rb +++ b/lib/shotstack/version.rb @@ -11,5 +11,5 @@ =end module Shotstack - VERSION = '1.10.4' + VERSION = '1.16.0' end