我的目标是:我试图允许用户在我的网站中嵌入指向Youtube视频的链接,同时让我控制播放器的设置。
我想通过仅要求用户提供链接(而不是整个嵌入代码)来做到这一点,从那里我可以以某种方式将该链接粘贴到嵌入代码中。
我尝试用一些 Youtube 链接(http://youtu.be/...
)进行简单的替换,但它们不起作用,说"电影未加载"。有没有可靠的方法可以做到这一点?
我经常为客户这样做,它的要点是你从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>
我把它放在一个助手中。根据口味更改高度、宽度和选项。
另一个答案是使用这个处理YouTube和vimeo的宝石,并且可以扩展到更多。 它还与AR很好地集成,因此您可以缓存生成的html,而不是在每个渲染上进行过滤:
https://github.com/dejan/auto_html
我使用了关于函数的最高评分答案youtube_embed但是当我在我的视图中实现时,我看到iframe代码出现在我的页面中,但没有视频。 我在函数调用之前添加了 raw,现在页面一切都很好。
在我的视野中.html.erb
<p><%= raw(youtube_embed(@experiment.researchsection.videolink)) %></p>
像这样的东西(例如在模型中):
@@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
和样本部分(哈姆尔):
%iframe{:allowfullscreen => "", :frameborder => "0", :height => "349",
:src => "http://www.youtube.com/embed/#{id}", :width => "560"}
并查看简单如下:
= youtube_video Model.video_id
这是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 链接的概念验证正则表达式:
- http://rubular.com/r/Fitt7PPJW1
以下是用于匹配 youtu.be 链接的概念证明正则表达式:
- http://rubular.com/r/MTgd9nXzFA
请注意,嵌入网址也可以加载到浏览器中,这将打开一个全屏视频页面。
我不得不在我最近的一个项目中加入这个功能。我必须支持链接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 + "&hl=en_US&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
您可能更喜欢推出自己的解决方案,但值得考虑嵌入式 API。 http://embed.ly/
我认为实现您要做的事情的最简单方法是:
您正在尝试从中获取:
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) %>
我创建了一个简单的帮助程序来嵌入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
假设您有一个文章模型,其中包含一个名为 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? ..要实现相同的验证,请执行以下操作:
#show (before_save)
# Returns a string (html_safe) .. iframe element from the embed string field
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>").html_safe
## 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>").html_safe
### Validate + Generate iframe for whatever other embeds you want to allow (Google Maps, Vimeo, etc)
# elsif
else
self.embed = nil
end
end
end
在文章#show视图中(注意..用于处理响应性的引导类):
<% if @article.embed.present? # no markup if nil %>
<div class="embed-responsive embed-responsive-16by9">
<%= @article.iframe %>
</div><!-- .embed-responsive -->
<% end %>
如果要获取嵌入的缩略图,此方法的工作方式相同:
#_articles (before_save)
# Returns a string (html_safe) .. img element from the embed string field
def thumb
if self.embed.present?
### YouTube
## Each YouTube video has 4 generated images [ /0 .. /3 ]
if self.embed =~ /^(https?://)?(www.)?youtube.com/watch?v=/
("<img alt='Media' class='card-img-top' src='https://img.youtube.com/vi/#{self.embed[32..42]}/0.jpg' />").html_safe
elsif self.embed =~ /^(https?://)?(www.)?youtu.be//
("<img alt='Media' class='card-img-top' src='https://img.youtube.com/vi/#{self.embed[17..27]}/0.jpg' />").html_safe
else
self.embed = nil
end
end
end
因此,在文章#索引视图中,您可以调用 thumb 方法:
<% if article.embed.present? %>
<%= link_to article.thumb, article_path(article) %>
<% end %>
在每种情况下,您都将在 article.rb 模型中使用 activerecord 回调:
before_save :iframe, :thumb