Converting a regular Youtube 'link' into a

2020-05-11 10:58发布

问题:

My goal: I am trying to allow users to embed a link to a Youtube video in my site, while giving me control over the player's settings.

I would like to do this by only asking the user to supply the link (not the entire embed code), from where I can somehow paste that link into the embed code.

I've tried doing a simple substitution with a few Youtube links (http://youtu.be/...) but they don't work, saying 'movie not loaded'. Is there a dependable way to do this?

回答1:

I do this quite often for clients, the gist of it is that you parse out the ID from the URL, then generate the iframe HTML using this.

def youtube_embed(youtube_url)
  if youtube_url[/youtu\.be\/([^\?]*)/]
    youtube_id = $1
  else
    # Regex from # http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url/4811367#4811367
    youtube_url[/^.*((v\/)|(embed\/)|(watch\?))\??v?=?([^\&\?]*).*/]
    youtube_id = $5
  end

  %Q{<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/#{ youtube_id }" frameborder="0" allowfullscreen></iframe>}
end

youtube_embed('youtu.be/jJrzIdDUfT4')
# => <iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/jJrzIdDUfT4" frameborder="0" allowfullscreen></iframe>

I put this in a helper. Change the height, width and options to taste.



回答2:

Another answer is to use this gem which handles youtube and vimeo, and could be expanded to more. It also integrates well with AR so you can cache the resulting html instead of filtering on each render:

https://github.com/dejan/auto_html



回答3:

I used the highest rated answer about with the function youtube_embed but when I implemented in my view I was seeing the iframe code appear in my page, but no video. I added raw before the function call and all is good with the page now.

Inside my view.html.erb

<p><%= raw(youtube_embed(@experiment.researchsection.videolink)) %></p>


回答4:

something like this (for ex. in model):

@@video_regexp = [ /^(?:https?:\/\/)?(?:www\.)?youtube\.com(?:\/v\/|\/watch\?v=)([A-Za-z0-9_-]{11})/, 
                   /^(?:https?:\/\/)?(?:www\.)?youtu\.be\/([A-Za-z0-9_-]{11})/,
                   /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/user\/[^\/]+\/?#(?:[^\/]+\/){1,4}([A-Za-z0-9_-]{11})/
                   ]

def video_id
  @@video_regexp.each { |m| return m.match(source_url)[1] unless m.nil? }
end

where source_url is the full link to video. then a helper:

def youtube_video(video_id)
  render :partial => 'youtube_video', :locals => { :id => video_id }
end

and sample partial (haml):

%iframe{:allowfullscreen => "", :frameborder => "0", :height => "349",
        :src => "http://www.youtube.com/embed/#{id}", :width => "560"}

and in view as simple as:

= youtube_video Model.video_id


回答5:

This is what youtube uses:

<iframe width="425" height="349" src="http://www.youtube.com/embed/zb-gmJVW5lw" frameborder="0" allowfullscreen></iframe>

Then just use a regexp to change the link from:

http://www.youtube.com/watch?v=zb-gmJVW5lw

into:

http://www.youtube.com/embed/zb-gmJVW5lw

Here's a proof of concept regexp for matching regular youtube links:

  • http://rubular.com/r/Fitt7PPJW1

And here's a proof of concept regexp for matching youtu.be links:

  • http://rubular.com/r/MTgd9nXzFA

Note that the embed url can also be loaded in the browser which opens a page where the video is fullscreen.



回答6:

I had to incorporate this functionality in one of my recent projects. I had to support linking both YouTube and Vimeo videos. I am using the 'uri' module of Ruby and the HTTParty. Basically I came with the following:

class LinkVideo < ActiveRecord::Base
  require 'uri'
  include HTTParty

  cattr_reader :per_page
  @@per_page = 12

  belongs_to :user

  validates :weblink, :presence => true, :domain => true


  def embed(width = "640", height = "390")
    embed_code = nil

    case base_uri
      when "www.youtube.com"
        embed_code = "<object width='#{width}' height='#{height}'>" +
              "<param name='movie' value='#{url}'></param>" +
              "<param name='allowFullScreen' value='false'></param>" +
              "<param name='allowscriptaccess' value='always'></param>" +
              "<embed src='#{url}' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='false' 
                  width='#{width}' height='#{height}'> </embed>" +
            "</object>"
        when "www.vimeo.com"
          embed_code = "<iframe src='#{url}' width='#{width}' height='#{height}' frameborder='0'></iframe>"
      end

      embed_code
  end

  def url
    url = nil
    case base_uri
      when "www.youtube.com"
        url = "http://www.youtube.com/v/" + video_id + "&amp;hl=en_US&amp;fs=1"
      when "www.vimeo.com"
        url = "http://player.vimeo.com/video/" + video_id
    end

    url
  end

  def thumbnail
    url = nil
    case base_uri
      when "www.youtube.com"  
        url = "http://img.youtube.com/vi/" + video_id + "/2.jpg"
      when "www.vimeo.com"
        url = thumbnail_path( image_base_uri, video_id )
    end

    url  
  end

  # Video Paths:
  #   http://www.youtube.com/watch?v=Gqraan6sBjk
  #   http://www.vimeo.com/21618919
  # Thumbnail Paths:
  #   http://img.youtube.com/vi/Gqraan6sBjk/2.jpg
  private
    def image_base_uri
      image_base_uri = nil
      case base_uri
        when "www.youtube.com"
          image_base_uri = "http://img.youtube.com/vi/"
        when "www.vimeo.com"
          image_base_uri = "http://vimeo.com/api/v2/video/"
      end

      image_base_uri
    end

    def thumbnail_path(base_uri, videoid = nil, format = 'xml')
      path = nil

      return path if base_uri.nil?

      xml     = HTTParty.get( base_uri + ( videoid.nil? ? video_id : videoid ) + format.insert(0, '.') )
      values  = xml.parsed_response.values_at("videos").first.fetch('video')
      if values["user_portrait_medium"].include?('100')
        path  = values["user_portrait_medium"]
      else values["user_portrait_large"].include?('100')
        path = values["user_portrait_large"]
      end

      path
    end

    def base_uri
      @uri ||= parse_it

      @uri.host
    end

    def video_id
      video_id = nil
      case base_uri
        when "www.youtube.com"
          video_id = @uri.query.split('=')[1].slice(0, 11)
        when "www.vimeo.com"
          video_id = @uri.path.delete('/')
      end

      video_id
    end

    def parse_it
      @uri = URI.parse( weblink )
    end
end


回答7:

You might prefer to roll your own solution, but it's worth considering the Embedly API. http://embed.ly/



回答8:

I think the simplest way to achieve what you're trying to do is the following:

You're trying to get from this:

http://www.youtube.com/watch?v=zb-gmJVW5lw

To this:

<iframe width="640" height="360" src="http://www.youtube.com/embed/zb-gmJVW5l" frameborder="0" allowfullscreen></iframe>

So you can just simply do this:

#### Use a regular expression to extract the video code
@video_id = (/([\w-]{11})/.match(@v_url)).to_s
#### Put this information in the right format
@embed_code = "<iframe width='640' height='360' src='http://www.youtube.com/embed/#{@video_id}' frameborder='0' allowfullscreen></iframe>"

And then in your view, just do:

<%= raw(@embed_code) %>


回答9:

I have created a simple helper to embed YouTube videos:

# Helpers for better embedding and manipulation of videos
module VideosHelper
  # Regex to find YouTube's video ID
  YOUTUBE_REGEX = %r(^(http[s]*:\/\/)?(www.)?(youtube.com|youtu.be)\/(watch\?v=){0,1}([a-zA-Z0-9_-]{11}))

  # Embeds YouTube video of given URL in an iframe
  #
  # @param url [String] URL of desired video
  # @param width [String] width of embedded video. Can be any valid CSS unit
  # @param height [String] height of embedded video. Can be any valid CSS unit
  # @return [String] HTML string of embedded video
  def youtube_embed(url, width = "100%", height = "250px")
    youtube_id = find_youtube_id(url)

    result = %(<iframe title="YouTube video player" width="#{width}"
                height="#{height}" src="//www.youtube.com/embed/#{ youtube_id }"
                frameborder="0" allowfullscreen></iframe>)
    result.html_safe
  end

  # Finds YouTube's video ID from given URL or [nil] if URL is invalid
  # The video ID matches the RegEx \[a-zA-Z0-9_-]{11}\
  #
  # @param url [String] URL of desired video
  # @return [String] video ID of given URL
  def find_youtube_id(url)
    url = sanitize(url).to_str

    matches = YOUTUBE_REGEX.match url

    if matches
      matches[6] || matches[5]
    end
  end
end