lib/cloudinary/video_helper.rb in cloudinary-1.17.1 vs lib/cloudinary/video_helper.rb in cloudinary-1.18.0

- old
+ new

@@ -1,16 +1,37 @@ module CloudinaryHelper include ActionView::Helpers::CaptureHelper DEFAULT_POSTER_OPTIONS = { :format => 'jpg', :resource_type => 'video' } DEFAULT_SOURCE_TYPES = %w(webm mp4 ogv) DEFAULT_VIDEO_OPTIONS = { :resource_type => 'video' } + DEFAULT_SOURCES = [ + { + :type => "mp4", + :codecs => "hev1", + :transformations => { :video_codec => "h265" } + }, + { + :type => "webm", + :codecs => "vp9", + :transformations => { :video_codec => "vp9" } + }, + { + :type => "mp4", + :transformations => { :video_codec => "auto" } + }, + { + :type => "webm", + :transformations => { :video_codec => "auto" } + } + ] # Creates an HTML video tag for the provided +source+ # # ==== Options # * <tt>:source_types</tt> - Specify which source type the tag should include. defaults to webm, mp4 and ogv. # * <tt>:source_transformation</tt> - specific transformations to use for a specific source type. + # * <tt>:sources</tt> - list of sources (overrides :source_types when present) # * <tt>:poster</tt> - override default thumbnail: # * url: provide an ad hoc url # * options: with specific poster transformations and/or Cloudinary +:public_id+ # # ==== Examples @@ -18,10 +39,21 @@ # cl_video_tag("mymovie.mp4", :source_types => :webm) # cl_video_tag("mymovie.ogv", :poster => "myspecialplaceholder.jpg") # cl_video_tag("mymovie.webm", :source_types => [:webm, :mp4], :poster => {:effect => 'sepia'}) do # content_tag( :span, "Cannot present video!") # end + # cl_video_tag("mymovie", :sources => [ + # { + # :type => "mp4", + # :codecs => "hev1", + # :transformations => { :video_codec => "h265" } + # }, + # { + # :type => "webm", + # :transformations => { :video_codec => "auto" } + # } + # ]) def cl_video_tag(source, options = {}, &block) source = strip_known_ext(source) video_attributes = [:autoplay,:controls,:loop,:muted,:poster, :preload] options = Cloudinary::Utils.deep_symbolize_keys(DEFAULT_VIDEO_OPTIONS.merge(options)) @@ -46,34 +78,16 @@ end else video_options[:poster] = cl_video_thumbnail_path(source, options) end - source_transformation = options.delete(:source_transformation) || {} - source_types = Array(options.delete(:source_types)) - fallback = (capture(&block) if block_given?) || options.delete(:fallback_content) + fallback = (capture(&block) if block_given?) || options.delete(:fallback_content) - if source_types.size > 1 - cloudinary_tag(source, options) do |_source, tag_options| - content_tag('video', tag_options.merge(video_options)) do - source_tags = source_types.map do |type| - transformation = source_transformation[type.to_sym] || {} - cloudinary_tag("#{source}.#{type}", options.merge(transformation)) do |url, _tag_options| - mime_type = "video/#{(type == 'ogv' ? 'ogg' : type)}" - tag("source", :src => url, :type => mime_type) - end - end - source_tags.push(fallback.html_safe) unless fallback.blank? - safe_join(source_tags) - end - end + if options[:sources] + video_tag_from_sources(source, options, video_options, fallback) else - transformation = source_transformation[source_types.first.to_sym] || {} - video_options[:src] = cl_video_path("#{source}.#{source_types.first.to_sym}", transformation.merge(options)) - cloudinary_tag(source, options) do |_source, tag_options| - content_tag('video', fallback, tag_options.merge(video_options)) - end + video_tag_from_source_types(source, options, video_options, fallback) end end # Returns a url for the given source with +options+ def cl_video_path(source, options={}) @@ -94,9 +108,69 @@ def strip_known_ext(name) name.sub(/\.(#{DEFAULT_SOURCE_TYPES.join("|")})$/, '') end + private + + def video_tag_from_source_types(source_name, options, video_options, fallback) + source_transformation = options.delete(:source_transformation) || {} + source_types = Array(options.delete(:source_types)) + + if source_types.size > 1 + sources = source_types.map do |type| + { + :type => type, + :transformations => source_transformation[type.to_sym] || {} + } + end + + generate_tag_from_sources(:source_name => source_name, + :sources => sources, + :options => options, + :video_options => video_options, + :fallback => fallback) + else + transformation = source_transformation[source_types.first.to_sym] || {} + video_options[:src] = cl_video_path("#{source_name}.#{source_types.first.to_sym}", transformation.merge(options)) + cloudinary_tag(source_name, options) do |_source, tag_options| + content_tag('video', fallback, tag_options.merge(video_options)) + end + end + end + + def video_tag_from_sources(source_name, options, video_options, fallback) + sources = options.delete(:sources) + + generate_tag_from_sources(:source_name => source_name, + :sources => sources, + :options => options, + :video_options => video_options, + :fallback => fallback) + end + + def generate_tag_from_sources(params) + source_name, sources, options, video_options, fallback = params.values_at(:source_name, :sources, :options, :video_options, :fallback) + + cloudinary_tag(source_name, options) do |_source, tag_options| + content_tag('video', tag_options.merge(video_options)) do + source_tags = sources.map do |source| + type = source[:type] + transformation = source[:transformations] || {} + cloudinary_tag("#{source_name}.#{type}", options.merge(transformation)) do |url, _tag_options| + mime_type = "video/#{(type == 'ogv' ? 'ogg' : type)}" + if source[:codecs] + codecs = source[:codecs].is_a?(Array) ? source[:codecs].join(", ") : source[:codecs] + mime_type = "#{mime_type}; codecs=#{codecs}" + end + tag("source", :src => url, :type => mime_type) + end + end + source_tags.push(fallback.html_safe) unless fallback.blank? + safe_join(source_tags) + end + end + end end