Converting a regular Youtube 'link' into an embedded video

前端 未结 10 1834
别那么骄傲
别那么骄傲 2021-01-30 02:25

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 a

相关标签:
10条回答
  • 2021-01-30 03:17

    Let's say you have an Article model with a field (string) called embed :

    YouTube examples to handle:

    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

    etc..

    In the model (note.. I'm not applying width and height in the iframe output, because I'll handle it globally in a stylesheet. Also, you can remove that regex and uncomment self.embed.include? .. to achieve the same validation):

      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
    

    In the articles#show view (note.. bootstrap classes for handling responsiveness):

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

    If you want to grab the thumbnail for the embed, this method works the same way:

      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='http://img.youtube.com/vi/#{self.embed[32..42]}/0.jpg' />"
          elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\//
            "<img alt='Media' class='card-img-top' src='http://img.youtube.com/vi/#{self.embed[17..27]}/0.jpg' />"
          else
            self.embed = nil
          end
        end
      end
    

    So, in the articles#index view, you could call on the thumb method:

    <% if article.embed.present? %>
      <%= link_to article.thumb.html_safe, article_path(article) %>
    <% end # consider else.. fallback image ..end %>
    

    Working Example: https://rails-react-bootstrap.herokuapp.com/articles/45

    0 讨论(0)
  • 2021-01-30 03:20

    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
    
    0 讨论(0)
  • 2021-01-30 03:24

    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>
    
    0 讨论(0)
  • 2021-01-30 03:24

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

    0 讨论(0)
提交回复
热议问题