[feature] Use gifv type for short soundless mp4 videos (#3182)
This commit is contained in:
parent
3045782b49
commit
b19cfee7ae
|
@ -91,6 +91,7 @@ const (
|
||||||
FileTypeImage FileType = 1 // FileTypeImage is for jpegs, pngs, and standard gifs
|
FileTypeImage FileType = 1 // FileTypeImage is for jpegs, pngs, and standard gifs
|
||||||
FileTypeAudio FileType = 2 // FileTypeAudio is for audio-only files (no video)
|
FileTypeAudio FileType = 2 // FileTypeAudio is for audio-only files (no video)
|
||||||
FileTypeVideo FileType = 3 // FileTypeVideo is for files with audio + visual
|
FileTypeVideo FileType = 3 // FileTypeVideo is for files with audio + visual
|
||||||
|
FileTypeGifv FileType = 4 // FileTypeGifv is for short video-only files (20s or less, mp4, no audio).
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns a stringified, frontend API compatible form of FileType.
|
// String returns a stringified, frontend API compatible form of FileType.
|
||||||
|
@ -104,6 +105,8 @@ func (t FileType) String() string {
|
||||||
return "audio"
|
return "audio"
|
||||||
case FileTypeVideo:
|
case FileTypeVideo:
|
||||||
return "video"
|
return "video"
|
||||||
|
case FileTypeGifv:
|
||||||
|
return "gifv"
|
||||||
default:
|
default:
|
||||||
panic("invalid filetype")
|
panic("invalid filetype")
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,15 @@ func (res *result) GetFileType() (gtsmodel.FileType, string) {
|
||||||
case "mov,mp4,m4a,3gp,3g2,mj2":
|
case "mov,mp4,m4a,3gp,3g2,mj2":
|
||||||
switch {
|
switch {
|
||||||
case len(res.video) > 0:
|
case len(res.video) > 0:
|
||||||
return gtsmodel.FileTypeVideo, "mp4"
|
if len(res.audio) == 0 &&
|
||||||
|
res.duration <= 30 {
|
||||||
|
// Short, soundless
|
||||||
|
// video file aka gifv.
|
||||||
|
return gtsmodel.FileTypeGifv, "mp4"
|
||||||
|
} else {
|
||||||
|
// Video file (with or without audio).
|
||||||
|
return gtsmodel.FileTypeVideo, "mp4"
|
||||||
|
}
|
||||||
case len(res.audio) > 0 &&
|
case len(res.audio) > 0 &&
|
||||||
res.audio[0].codec == "aac":
|
res.audio[0].codec == "aac":
|
||||||
// m4a only supports [aac] audio.
|
// m4a only supports [aac] audio.
|
||||||
|
|
|
@ -202,7 +202,8 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
|
||||||
|
|
||||||
switch p.media.Type {
|
switch p.media.Type {
|
||||||
case gtsmodel.FileTypeImage,
|
case gtsmodel.FileTypeImage,
|
||||||
gtsmodel.FileTypeVideo:
|
gtsmodel.FileTypeVideo,
|
||||||
|
gtsmodel.FileTypeGifv:
|
||||||
// Attempt to clean as metadata from file as possible.
|
// Attempt to clean as metadata from file as possible.
|
||||||
if err := clearMetadata(ctx, temppath); err != nil {
|
if err := clearMetadata(ctx, temppath); err != nil {
|
||||||
return gtserror.Newf("error cleaning metadata: %w", err)
|
return gtserror.Newf("error cleaning metadata: %w", err)
|
||||||
|
|
|
@ -26,6 +26,8 @@ const Prism = require("./prism.js");
|
||||||
Prism.manual = true;
|
Prism.manual = true;
|
||||||
Prism.highlightAll();
|
Prism.highlightAll();
|
||||||
|
|
||||||
|
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||||
|
|
||||||
let [_, _user, type, id] = window.location.pathname.split("/");
|
let [_, _user, type, id] = window.location.pathname.split("/");
|
||||||
if (type == "statuses") {
|
if (type == "statuses") {
|
||||||
let firstStatus = document.getElementsByClassName("thread")[0].children[0];
|
let firstStatus = document.getElementsByClassName("thread")[0].children[0];
|
||||||
|
@ -49,9 +51,12 @@ new PhotoswipeCaptionPlugin(lightbox, {
|
||||||
|
|
||||||
lightbox.addFilter('itemData', (item) => {
|
lightbox.addFilter('itemData', (item) => {
|
||||||
const el = item.element;
|
const el = item.element;
|
||||||
if (el && el.classList.contains("plyr-video")) {
|
if (
|
||||||
|
el &&
|
||||||
|
el.classList.contains("plyr-video") &&
|
||||||
|
el._plyrContainer !== undefined
|
||||||
|
) {
|
||||||
const parentNode = el._plyrContainer.parentNode;
|
const parentNode = el._plyrContainer.parentNode;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
alt: el.getAttribute("alt"),
|
alt: el.getAttribute("alt"),
|
||||||
_video: {
|
_video: {
|
||||||
|
@ -118,13 +123,14 @@ dynamicSpoiler("text-spoiler", (spoiler) => {
|
||||||
dynamicSpoiler("media-spoiler", (spoiler) => {
|
dynamicSpoiler("media-spoiler", (spoiler) => {
|
||||||
const eye = spoiler.querySelector(".eye.button");
|
const eye = spoiler.querySelector(".eye.button");
|
||||||
const video = spoiler.querySelector(".plyr-video");
|
const video = spoiler.querySelector(".plyr-video");
|
||||||
|
const loopingAuto = !reduceMotion.matches && video != null && video.classList.contains("gifv");
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (spoiler.open) {
|
if (spoiler.open) {
|
||||||
eye.setAttribute("aria-label", "Hide media");
|
eye.setAttribute("aria-label", "Hide media");
|
||||||
} else {
|
} else {
|
||||||
eye.setAttribute("aria-label", "Show media");
|
eye.setAttribute("aria-label", "Show media");
|
||||||
if (video) {
|
if (video && !loopingAuto) {
|
||||||
video.pause();
|
video.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +138,22 @@ dynamicSpoiler("media-spoiler", (spoiler) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Array.from(document.getElementsByClassName("plyr-video")).forEach((video) => {
|
Array.from(document.getElementsByClassName("plyr-video")).forEach((video) => {
|
||||||
|
const loopingAuto = !reduceMotion.matches && video.classList.contains("gifv");
|
||||||
|
|
||||||
|
if (loopingAuto) {
|
||||||
|
// If we're able to play this as a
|
||||||
|
// looping gifv, then do so, else fall
|
||||||
|
// back to user-controllable video player.
|
||||||
|
video.draggable = false;
|
||||||
|
video.autoplay = true;
|
||||||
|
video.loop = true;
|
||||||
|
video.classList.remove("photoswipe-slide");
|
||||||
|
video.classList.remove("plry-video");
|
||||||
|
video.load();
|
||||||
|
video.play();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let player = new Plyr(video, {
|
let player = new Plyr(video, {
|
||||||
title: video.title,
|
title: video.title,
|
||||||
settings: ["loop"],
|
settings: ["loop"],
|
||||||
|
|
|
@ -99,7 +99,7 @@ media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{
|
||||||
<i class="hide fa fa-fw fa-eye-slash" aria-hidden="true"></i>
|
<i class="hide fa fa-fw fa-eye-slash" aria-hidden="true"></i>
|
||||||
<i class="show fa fa-fw fa-eye" aria-hidden="true"></i>
|
<i class="show fa fa-fw fa-eye" aria-hidden="true"></i>
|
||||||
</span>
|
</span>
|
||||||
{{- if eq .Type "video" }}
|
{{- if or (eq .Type "video") (eq .Type "gifv") }}
|
||||||
{{- include "videoPreview" $media | indent 4 }}
|
{{- include "videoPreview" $media | indent 4 }}
|
||||||
{{- else if eq .Type "image" }}
|
{{- else if eq .Type "image" }}
|
||||||
{{- include "imagePreview" $media | indent 4 }}
|
{{- include "imagePreview" $media | indent 4 }}
|
||||||
|
@ -107,11 +107,17 @@ media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{
|
||||||
{{- include "audioPreview" $media | indent 4 }}
|
{{- include "audioPreview" $media | indent 4 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
</summary>
|
</summary>
|
||||||
{{- if eq .Type "video" }}
|
{{- if or (eq .Type "video") (eq .Type "gifv") }}
|
||||||
<video
|
<video
|
||||||
|
{{- if eq .Type "video" }}
|
||||||
preload="none"
|
preload="none"
|
||||||
class="plyr-video photoswipe-slide"
|
{{- else }}
|
||||||
|
preload="auto"
|
||||||
|
muted
|
||||||
|
{{- end }}
|
||||||
|
class="plyr-video photoswipe-slide{{- if eq .Type "gifv" }} gifv{{ end }}"
|
||||||
controls
|
controls
|
||||||
|
playsinline
|
||||||
data-pswp-index="{{- $index -}}"
|
data-pswp-index="{{- $index -}}"
|
||||||
poster="{{- .PreviewURL -}}"
|
poster="{{- .PreviewURL -}}"
|
||||||
data-pswp-width="{{- $media.Meta.Small.Width -}}px"
|
data-pswp-width="{{- $media.Meta.Small.Width -}}px"
|
||||||
|
@ -128,6 +134,7 @@ media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{
|
||||||
preload="none"
|
preload="none"
|
||||||
class="plyr-video photoswipe-slide"
|
class="plyr-video photoswipe-slide"
|
||||||
controls
|
controls
|
||||||
|
playsinline
|
||||||
data-pswp-index="{{- $index -}}"
|
data-pswp-index="{{- $index -}}"
|
||||||
{{- if and $media.PreviewURL $media.Meta.Small.Width }}
|
{{- if and $media.PreviewURL $media.Meta.Small.Width }}
|
||||||
poster="{{- .PreviewURL -}}"
|
poster="{{- .PreviewURL -}}"
|
||||||
|
|
Loading…
Reference in New Issue