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:
parent
1122579216
commit
9dbae6e8a1
11 changed files with 151 additions and 44 deletions
|
@ -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
|
||||
|
|
|
@ -47,6 +47,10 @@ body {
|
|||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&.player {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.embed {
|
||||
background: transparent;
|
||||
margin: 0;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
2
app/views/media/player.html.haml
Normal file
2
app/views/media/player.html.haml
Normal 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 }
|
|
@ -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'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue