0
0
Fork 0

Save video metadata and improve video OpenGraph tags (#6481)

* Save metadata from video attachments, put correct dimensions into OG tags

* Add twitter:player for videos

* Fix code style and test
This commit is contained in:
Eugen Rochko 2018-02-16 07:22:20 +01:00 committed by GitHub
parent 1122579216
commit 9dbae6e8a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 151 additions and 44 deletions

View file

@ -3,20 +3,26 @@
class MediaController < ApplicationController
include Authorization
before_action :verify_permitted_status
before_action :set_media_attachment
before_action :verify_permitted_status!
def show
redirect_to media_attachment.file.url(:original)
redirect_to @media_attachment.file.url(:original)
end
def player
@body_classes = 'player'
raise ActiveRecord::RecordNotFound unless @media_attachment.video? || @media_attachment.gifv?
end
private
def media_attachment
MediaAttachment.attached.find_by!(shortcode: params[:id])
def set_media_attachment
@media_attachment = MediaAttachment.attached.find_by!(shortcode: params[:id] || params[:medium_id])
end
def verify_permitted_status
authorize media_attachment.status, :show?
def verify_permitted_status!
authorize @media_attachment.status, :show?
rescue Mastodon::NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code
raise ActiveRecord::RecordNotFound

View file

@ -47,6 +47,10 @@ body {
padding-bottom: 0;
}
&.player {
text-align: center;
}
&.embed {
background: transparent;
margin: 0;

View file

@ -65,6 +65,10 @@
}
}
.media-gallery__gifv__label {
bottom: 9px;
}
.status.light {
padding: 14px 14px 14px (48px + 14px * 2);
position: relative;
@ -258,12 +262,12 @@
.media-spoiler {
background: $ui-primary-color;
color: $white;
transition: all 100ms linear;
transition: all 40ms linear;
&:hover,
&:active,
&:focus {
background: darken($ui-primary-color, 5%);
background: darken($ui-primary-color, 2%);
color: unset;
}
}

View file

@ -160,23 +160,39 @@ class MediaAttachment < ApplicationRecord
meta = {}
file.queued_for_write.each do |style, file|
begin
geo = Paperclip::Geometry.from_file file
meta[style] = {
width: geo.width.to_i,
height: geo.height.to_i,
size: "#{geo.width.to_i}x#{geo.height.to_i}",
aspect: geo.width.to_f / geo.height.to_f,
}
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
meta[style] = {}
end
meta[style] = style == :small || image? ? image_geometry(file) : video_metadata(file)
end
meta
end
def image_geometry(file)
geo = Paperclip::Geometry.from_file file
{
width: geo.width.to_i,
height: geo.height.to_i,
size: "#{geo.width.to_i}x#{geo.height.to_i}",
aspect: geo.width.to_f / geo.height.to_f,
}
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
{}
end
def video_metadata(file)
movie = FFMPEG::Movie.new(file.path)
return {} unless movie.valid?
{
width: movie.width,
height: movie.height,
frame_rate: movie.frame_rate,
duration: movie.duration,
bitrate: movie.bitrate,
}
end
def appropriate_extension
mime_type = MIME::Types[file.content_type]

View file

@ -0,0 +1,2 @@
%video{ poster: @media_attachment.file.url(:small), preload: 'auto', autoplay: 'autoplay', muted: 'muted', loop: 'loop', controls: 'controls', style: "width: #{@media_attachment.file.meta.dig('original', 'width')}px; height: #{@media_attachment.file.meta.dig('original', 'height')}px" }
%source{ src: @media_attachment.file.url(:original), type: @media_attachment.file_content_type }

View file

@ -1,23 +1,34 @@
- if activity.is_a?(Status) && activity.media_attachments.any?
- player_card = false
- activity.media_attachments.each do |media|
- if media.image?
= opengraph 'og:image', full_asset_url(media.file.url(:original))
= opengraph 'og:image:type', media.file_content_type
- unless media.file.meta.nil?
= opengraph 'og:image:width', media.file.meta['original']['width']
= opengraph 'og:image:height', media.file.meta['original']['height']
- elsif media.video?
= opengraph 'og:image:width', media.file.meta.dig('original', 'width')
= opengraph 'og:image:height', media.file.meta.dig('original', 'height')
- elsif media.video? || media.gifv?
- player_card = true
= opengraph 'og:image', full_asset_url(media.file.url(:small))
= opengraph 'og:image:type', 'image/png'
- unless media.file.meta.nil?
= opengraph 'og:image:width', media.file.meta['small']['width']
= opengraph 'og:image:height', media.file.meta['small']['height']
= opengraph 'og:image:width', media.file.meta.dig('small', 'width')
= opengraph 'og:image:height', media.file.meta.dig('small', 'height')
= opengraph 'og:video', full_asset_url(media.file.url(:original))
= opengraph 'og:video:secure_url', full_asset_url(media.file.url(:original))
= opengraph 'og:video:type', media.file_content_type
= opengraph 'twitter:player', medium_player_url(media)
= opengraph 'twitter:player:stream', full_asset_url(media.file.url(:original))
= opengraph 'twitter:player:stream:content_type', media.file_content_type
- unless media.file.meta.nil?
= opengraph 'og:video:width', media.file.meta['small']['width']
= opengraph 'og:video:height', media.file.meta['small']['height']
= opengraph 'twitter:card', 'summary_large_image'
= opengraph 'og:video:width', media.file.meta.dig('original', 'width')
= opengraph 'og:video:height', media.file.meta.dig('original', 'height')
= opengraph 'twitter:player:width', media.file.meta.dig('original', 'width')
= opengraph 'twitter:player:height', media.file.meta.dig('original', 'height')
- if player_card
= opengraph 'twitter:card', 'player'
- else
= opengraph 'twitter:card', 'summary_large_image'
- else
= opengraph 'og:image', full_asset_url(account.avatar.url(:original))
= opengraph 'og:image:width', '120'