将常规Youtube“链接”转换为嵌入式视频

时间:2011-05-06 09:02:04

标签: ruby-on-rails ruby-on-rails-3 youtube

我的目标:我正在尝试允许用户在我的网站中嵌入Youtube视频的链接,同时让我控制播放器的设置。

我想通过只要求用户提供链接(而不是整个嵌入代码)来实现这一点,我可以从那里将链接粘贴到嵌入代码中。

我尝试使用一些Youtube链接(http://youtu.be/...)进行简单替换,但它们不起作用,说“电影未加载”。有可靠的方法吗?

10 个答案:

答案 0 :(得分:68)

我经常为客户做这件事,要点是你从URL解析出来的ID,然后使用它生成iframe HTML。

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>

我把它放在帮助器里。改变高度,宽度和选择。

答案 1 :(得分:7)

另一个答案是使用这个处理youtube和vimeo的gem,可以扩展到更多。它还可以与AR集成,因此您可以缓存生成的html,而不是在每个渲染上进行过滤:

https://github.com/dejan/auto_html

答案 2 :(得分:7)

我使用youtube_embed函数获得了最高评价的答案但是当我在我的视图中实现时,我看到iframe代码出现在我的页面中,但没有视频。我在函数调用之前添加了raw,现在页面都很好。

在我的view.html.erb

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

答案 3 :(得分:4)

类似的东西(例如模型中):

@@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

其中source_url是视频的完整链接。 然后是帮助者:

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

和样本部分(haml):

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

并且看起来很简单:

= youtube_video Model.video_id

答案 4 :(得分:3)

这是youtube使用的:

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

然后只需使用正则表达式来更改链接:

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

成:

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

以下是匹配常规YouTube链接的概念证明regexp:

这是匹配youtu.be链接的概念证明regexp:

请注意,嵌入式网址也可以在浏览器中加载,从而打开视频全屏的页面。

答案 5 :(得分:3)

我必须在最近的一个项目中加入这个功能。我必须支持链接YouTube和Vimeo视频。我正在使用Ruby和HTTParty的'uri'模块。基本上我带来了以下内容:

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

答案 6 :(得分:2)

您可能更愿意推出自己的解决方案,但值得考虑使用Embedly API。 http://embed.ly/

答案 7 :(得分:1)

我认为实现您尝试做的最简单的方法如下:

你正试图摆脱这个:

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

对此:

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

所以你可以这样做:

#### 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>"

然后在你看来,这样做:

<%= raw(@embed_code) %>

答案 8 :(得分:1)

我创建了一个简单的帮助器来嵌入YouTube视频:

# 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

答案 9 :(得分:0)

假设您有一个 Article 模型,其中的字段(字符串)称为 embed

要处理的YouTube示例:

https://www.youtube.com/watch?v=u75Zsl1ECPQ&list=PLu9lbDbw-S8zyBwu9_aA2nE-3QocgyzRE&index=4

https://www.youtube.com/watch?v=u75Zsl1ECPQ

https://youtu.be/u75Zsl1ECPQ

https://youtu.be/u75Zsl1ECPQ?t=12

等。

在模型中(请注意。我不在iframe输出中应用宽度和高度,因为我将在样式表中对其进行全局处理。此外,您可以删除该正则表达式并取消注释self.embed.include?。 。以实现相同的验证):

  before_save :iframe

  def iframe
    if self.embed.present?
      ### YouTube
      ## Browser link --- use array to handle most playlist links, etc
      if self.embed =~ /^(https?:\/\/)?(www\.)?youtube.com\/watch\?v=/  # self.embed.include? 'https://www.youtube.com/watch?v='
        "<iframe src='https://www.youtube.com/embed/#{self.embed[32..42]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>"
      ## YouTube share link --- using array, because .split('https://youtu.be/').last wouldn't handle start at option ()?t=12)
      elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\//  # self.embed.include? 'https://youtu.be/'
        "<iframe src='https://www.youtube.com/embed/#{self.embed[17..27]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>"
      ### Validate + Generate iframe for whatever other embeds you want to allow (Google Maps, Vimeo, etc)
      # elsif
      else
        self.embed = nil
      end
    end
  end

在#show视图中(注意:用于处理响应性的bootstrap类):

  <% if @article.embed.present? %> <!-- no markup if nil -->
    <div class="embed-responsive embed-responsive-16by9">
      <%= @article.iframe.html_safe %>
    </div><!-- .embed-responsive -->
  <% end %>

就是这样