defmodule SEO.OpenGraph.Video do @moduledoc """ Data describing a video. Commonly, an `og:video` is accompanied with an `og:image` that provides the preview image for the video. ### Resources - https://ogp.me/#structured - https://developers.facebook.com/docs/sharing/webmasters/#video - https://yandex.com/support/video/partners/open-graph.html """ use Phoenix.Component alias SEO.Utils defstruct [ :url, :secure_url, :type, :width, :height, :ya_bitrate, :ya_quality, :ya_allow_embed, :alt ] @type t :: %__MODULE__{ url: URI.t() | String.t(), secure_url: URI.t() | String.t() | nil, type: mime(), width: pixels(), height: pixels(), ya_bitrate: yandex_bitrate(), ya_quality: yandex_quality(), ya_allow_embed: boolean() | nil, alt: String.t() | nil } @type mime :: String.t() | nil @type pixels :: pos_integer() | nil @type yandex_bitrate :: pos_integer() | nil @type yandex_quality :: :low | :medium | :hd | :full_hd | nil @doc """ The `og:video` property has some optional structured properties: - `:url` - The url with metadata that describes the video. - `:secure_url` - An alternate url to use if the webpage requires HTTPS. If the URL starts with `https` then - `:type` - A MIME type for this video. Facebook supports both mp4 and Flash videos, `application/x-shockwave-flash` or `video/mp4`, but please for the love of all that is holy don't use Shockwave Flash. - `:width` - The width in pixels. - `:height` - The height in pixels. - `:alt` - A description of what is in the video (not a caption). If the page specifies an `og:video` it should specify `og:video:alt`. Supply a secure URL for both the `og:video:url` and `og:video:secure_url` tags to make your video eligible to play in-line in Facebook's Feed. For Yandex, there are additional properties: - `:ya_bitrate` - Maximum bitrate in kilobits per second - `:ya_allow_embed` - Allow embedding in Yandex search results - `:ya_quality` - The quality in resolution and bitrate - `:low` - Low quality with resolution less than 360x640 and bitrate lower than 717kbps - `:medium` - Average quality with resolution between 360x640 and 720x1280 and bitrate between than 717kbps-1Mbps - `:hd` - HD quality with resolution between 720x1280 and 1080x1920 and bitrate between than 1MBps-2Mbps - `:full_hd` - 1080p quality with resolution greater than 1080x1920 and bitrate higher than 2Mbps """ @spec build(SEO.attrs(), SEO.config()) :: t() | nil def build(attrs, default \\ nil) def build(attrs, default) do __MODULE__ |> Utils.merge_defaults(attrs, default) |> maybe_put_secure_url() end defp maybe_put_secure_url(video) do case video.url do %URI{scheme: "https"} = uri -> %{video | secure_url: uri} "https" <> _ = url -> %{video | secure_url: url} _ -> video end end attr :content, :any, default: nil def meta(assigns) do case assigns[:content] do nil -> ~H"" %__MODULE__{} -> ~H""" <%= if @content.url || @content.secure_url do %> <%= if @content.url do %> <% end %><%= if @content.secure_url do %> <% end %><%= if @content.type do %> <% end %><%= if @content.width do %> <% end %><%= if @content.height do %> <% end %><%= if @content.alt do %> <% end %><%= if @content.ya_bitrate do %> <% end %><%= if @content.ya_quality do %> <% end %><%= if @content.ya_allow_embed do %> <% end %> <% end %> """ _url -> ~H""" """ end end defp format_ya_quality(nil), do: nil defp format_ya_quality(:low), do: "low" defp format_ya_quality(:medium), do: "medium" defp format_ya_quality(:hd), do: "HD" defp format_ya_quality(:full_hd), do: "full HD" end