about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-02-16 07:22:20 +0100
committerGitHub <noreply@github.com>2018-02-16 07:22:20 +0100
commit9dbae6e8a120fc18fdc007503375b53f6b061b8f (patch)
treecf0a3ceee2a1a0c4c1f1418ac9668992465bdfeb /app
parent1122579216a0ba6d081ff9ad14a1b501636f9601 (diff)
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
Diffstat (limited to 'app')
-rw-r--r--app/controllers/media_controller.rb18
-rw-r--r--app/javascript/styles/mastodon/basics.scss4
-rw-r--r--app/javascript/styles/mastodon/stream_entries.scss8
-rw-r--r--app/models/media_attachment.rb40
-rw-r--r--app/views/media/player.html.haml2
-rw-r--r--app/views/stream_entries/_og_image.html.haml27
6 files changed, 71 insertions, 28 deletions
diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb
index f652f5ace..88c7232dd 100644
--- a/app/controllers/media_controller.rb
+++ b/app/controllers/media_controller.rb
@@ -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
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss
index b5d77ff63..0e3b9ad6b 100644
--- a/app/javascript/styles/mastodon/basics.scss
+++ b/app/javascript/styles/mastodon/basics.scss
@@ -47,6 +47,10 @@ body {
     padding-bottom: 0;
   }
 
+  &.player {
+    text-align: center;
+  }
+
   &.embed {
     background: transparent;
     margin: 0;
diff --git a/app/javascript/styles/mastodon/stream_entries.scss b/app/javascript/styles/mastodon/stream_entries.scss
index a35bbee79..e11ca29d9 100644
--- a/app/javascript/styles/mastodon/stream_entries.scss
+++ b/app/javascript/styles/mastodon/stream_entries.scss
@@ -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;
     }
   }
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 4b84b95fa..b6e5916cb 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -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]
 
diff --git a/app/views/media/player.html.haml b/app/views/media/player.html.haml
new file mode 100644
index 000000000..ea868b3f6
--- /dev/null
+++ b/app/views/media/player.html.haml
@@ -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 }
diff --git a/app/views/stream_entries/_og_image.html.haml b/app/views/stream_entries/_og_image.html.haml
index bd14ef701..526034faa 100644
--- a/app/views/stream_entries/_og_image.html.haml
+++ b/app/views/stream_entries/_og_image.html.haml
@@ -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'