[feature] use webp for thumbnails (#3116)

* update to use webp for thumbnails

* bump webp quality up to 40% from 12% (it's a bit different to jpeg quality setting)

* update to use yuva colorspace, and use thumbnail=n=10 to select frame

* fix missing comma in ffmpeg args

* add links to appropriate ffmpeg docs

* update tests

* add file size tests for thumbnails

---------

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
kim 2024-07-19 15:28:43 +00:00 committed by GitHub
commit 50c9b5498b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 4496 additions and 225 deletions

View file

@ -721,19 +721,19 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 1200,
Height: 630,
Size: 756000,
Aspect: 1.9047619047619047,
Aspect: 1.9047619,
},
Small: gtsmodel.Small{
Width: 256,
Height: 134,
Size: 34304,
Aspect: 1.9104477611940298,
Width: 512,
Height: 268,
Size: 137216,
Aspect: 1.9104477,
},
},
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
Description: "Black and white image of some 50's style text saying: Welcome On Board",
ScheduledStatusID: "",
Blurhash: "LNJRdVM{00Rj%Mayt7j[4nWBofRj",
Blurhash: "LIIE|gRj00WB-;j[t7j[4nWBj[Rj",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH17FWEB39HZJ76B6VXSKF/attachment/original/01F8MH6NEM8D7527KZAECTCR76.jpg",
@ -741,10 +741,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 62529,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.jpg",
ContentType: "image/jpeg",
FileSize: 6872,
URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.jpg",
Path: "01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.webp",
ContentType: "image/webp",
FileSize: 5376,
URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -763,14 +763,14 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Original: gtsmodel.Original{
Width: 400,
Height: 280,
Size: 756000,
Aspect: 1.4285714285714286,
Size: 112000,
Aspect: 1.4285715,
},
Small: gtsmodel.Small{
Width: 256,
Height: 179,
Size: 45824,
Aspect: 1.4301675977653632,
Width: 400,
Height: 280,
Size: 112000,
Aspect: 1.4285715,
},
Focus: gtsmodel.Focus{
X: 0,
@ -780,7 +780,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "90's Trent Reznor turning to the camera",
ScheduledStatusID: "",
Blurhash: "LEDara58O=t5EMSOENEN9]}?aK%0",
Blurhash: "LCDRH758KOxsEMNxENEM9]}?aKxZ",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH7TDVANYKWVE8VVKFPJTJ.gif",
@ -788,10 +788,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 1109138,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.jpg",
ContentType: "image/jpeg",
FileSize: 8803,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.webp",
ContentType: "image/webp",
FileSize: 6336,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -811,16 +811,16 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 720,
Height: 404,
Size: 290880,
Aspect: 1.78217821782178,
Duration: util.Ptr[float32](15.033334),
Aspect: 1.7821782,
Duration: util.Ptr[float32](15.034),
Framerate: util.Ptr[float32](30.0),
Bitrate: util.Ptr[uint64](1206522),
Bitrate: util.Ptr[uint64](1209808),
},
Small: gtsmodel.Small{
Width: 720,
Height: 404,
Size: 290880,
Aspect: 1.78217821782178,
Width: 512,
Height: 287,
Size: 146944,
Aspect: 1.7839721,
},
Focus: gtsmodel.Focus{
X: 0,
@ -830,18 +830,18 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "A cow adorably licking another cow!",
ScheduledStatusID: "",
Blurhash: "",
Blurhash: "L9B|BBY8yZtS~AxZV@t6,njEjZV@",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01CDR64G398ADCHXK08WWTHEZ5.gif",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01CDR64G398ADCHXK08WWTHEZ5.mp4",
ContentType: "video/mp4",
FileSize: 2273532,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01CDR64G398ADCHXK08WWTHEZ5.jpg",
ContentType: "image/jpeg",
FileSize: 5272,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01CDR64G398ADCHXK08WWTHEZ5.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01CDR64G398ADCHXK08WWTHEZ5.webp",
ContentType: "image/webp",
FileSize: 5446,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01CDR64G398ADCHXK08WWTHEZ5.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -861,13 +861,13 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 800,
Height: 450,
Size: 360000,
Aspect: 1.7777777777777777,
Aspect: 1.7777778,
},
Small: gtsmodel.Small{
Width: 256,
Height: 144,
Size: 36864,
Aspect: 1.7777777777777777,
Width: 512,
Height: 288,
Size: 147456,
Aspect: 1.7777778,
},
Focus: gtsmodel.Focus{
X: 0,
@ -877,7 +877,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "the oh you meme",
ScheduledStatusID: "",
Blurhash: "LSAd]9ogDge-R:M|j=xWIto0xXWX",
Blurhash: "LNABP8o#Dge,S6M}axxVEQjYxWbH",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpg",
@ -885,10 +885,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 27759,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpg",
ContentType: "image/jpeg",
FileSize: 6177,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.webp",
ContentType: "image/webp",
FileSize: 4930,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -908,12 +908,12 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 1092,
Height: 1800,
Size: 1965600,
Aspect: 0.6066666666666667,
Aspect: 0.6066667,
},
Small: gtsmodel.Small{
Width: 155,
Height: 256,
Size: 39680,
Width: 310,
Height: 512,
Size: 158720,
Aspect: 0.60546875,
},
Focus: gtsmodel.Focus{
@ -924,7 +924,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "a green goblin looking nasty",
ScheduledStatusID: "",
Blurhash: "LKK9MT,p|YSNDkJ-5rsmvnwcOoe:",
Blurhash: "LHI:dk=G|rj]H[J-5roJvnr@Opag",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/avatar/original/01F8MH58A357CV5K7R7TJMSH6S.jpg",
@ -932,10 +932,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 457680,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpg",
ContentType: "image/jpeg",
FileSize: 15374,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.webp",
ContentType: "image/webp",
FileSize: 36188,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.webp",
RemoteURL: "",
},
Avatar: util.Ptr(true),
@ -955,13 +955,13 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 1018,
Height: 764,
Size: 777752,
Aspect: 1.3324607329842932,
Aspect: 1.3324608,
},
Small: gtsmodel.Small{
Width: 256,
Height: 192,
Size: 49152,
Aspect: 1.3333333333333333,
Width: 512,
Height: 384,
Size: 196608,
Aspect: 1.3333334,
},
Focus: gtsmodel.Focus{
X: 0,
@ -971,7 +971,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "A very old-school screenshot of the original team fortress mod for quake",
ScheduledStatusID: "",
Blurhash: "L26j{^WCs+R-N}jsxWj@4;WWxDoK",
Blurhash: "L17KPDs:$ykDJroJ-RoJ0fR+xVjY",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/header/original/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg",
@ -979,10 +979,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 517226,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg",
ContentType: "image/jpeg",
FileSize: 42308,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.webp",
ContentType: "image/webp",
FileSize: 10200,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -999,10 +999,13 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Type: gtsmodel.FileTypeAudio,
FileMeta: gtsmodel.FileMeta{
Original: gtsmodel.Original{
Width: 500,
Height: 500,
Size: 0,
Aspect: 0,
Width: 500,
Height: 500,
Size: 250000,
Aspect: 1,
Duration: util.Ptr[float32](185.62613),
Framerate: util.Ptr[float32](90000),
Bitrate: util.Ptr[uint64](322537),
},
Small: gtsmodel.Small{
Width: 500,
@ -1018,7 +1021,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
Description: "This is a track from Nine Inch Nail's \"Ghosts I-V\" album. This is the third track from \"Ghosts II\".",
ScheduledStatusID: "",
Blurhash: "LeDvfpayIUof01j[xuayxuayaxj[",
Blurhash: "LZDJO?ayIUof01j[xuayxuayayj[",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01J2M20K6K9XQC4WSB961YJHV6.mp3",
@ -1026,10 +1029,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 7483917,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01J2M20K6K9XQC4WSB961YJHV6.jpg",
ContentType: "image/jpeg",
FileSize: 6132,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01J2M20K6K9XQC4WSB961YJHV6.jpg",
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01J2M20K6K9XQC4WSB961YJHV6.webp",
ContentType: "image/webp",
FileSize: 4652,
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01J2M20K6K9XQC4WSB961YJHV6.webp",
RemoteURL: "",
},
Avatar: util.Ptr(false),
@ -1049,13 +1052,13 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 472,
Height: 291,
Size: 137352,
Aspect: 1.6219931271477663,
Aspect: 1.6219932,
},
Small: gtsmodel.Small{
Width: 472,
Height: 291,
Size: 137352,
Aspect: 1.6219931271477663,
Aspect: 1.6219932,
},
Focus: gtsmodel.Focus{
X: 0,
@ -1065,7 +1068,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "01F8MH5ZK5VRH73AKHQM6Y9VNX",
Description: "tweet from thoughts of dog: i drank. all the water. in my bowl. earlier. but just now. i returned. to the same bowl. and it was. full again.. the bowl. is haunted",
ScheduledStatusID: "",
Blurhash: "LARysgM_IU_3~pD%M_Rj_39FIAt6",
Blurhash: "L3Q9_@4n9E?axW4mD$Mx~q00Di%L",
Processing: 2,
File: gtsmodel.File{
Path: "01F8MH5ZK5VRH73AKHQM6Y9VNX/attachment/original/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpg",
@ -1073,11 +1076,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 19310,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01F8MH5ZK5VRH73AKHQM6Y9VNX/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpg",
ContentType: "image/jpeg",
FileSize: 11751,
URL: "http://localhost:8080/fileserver/01F8MH5ZK5VRH73AKHQM6Y9VNX/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpg",
RemoteURL: "http://fossbros-anonymous.io/attachments/small/a499f55b-2d1e-4acd-98d2-1ac2ba6d79b9.jpg",
Path: "01F8MH5ZK5VRH73AKHQM6Y9VNX/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.webp",
ContentType: "image/webp",
FileSize: 9128,
URL: "http://localhost:8080/fileserver/01F8MH5ZK5VRH73AKHQM6Y9VNX/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.webp",
},
Avatar: util.Ptr(false),
Header: util.Ptr(false),
@ -1096,13 +1098,13 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
Width: 472,
Height: 291,
Size: 137352,
Aspect: 1.6219931271477663,
Aspect: 1.6219932,
},
Small: gtsmodel.Small{
Width: 472,
Height: 291,
Size: 137352,
Aspect: 1.6219931271477663,
Aspect: 1.6219932,
},
Focus: gtsmodel.Focus{
X: 0,
@ -1112,7 +1114,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
AccountID: "062G5WYKY35KKD12EMSM3F8PJ8",
Description: "tweet from thoughts of dog: i drank. all the water. in my bowl. earlier. but just now. i returned. to the same bowl. and it was. full again.. the bowl. is haunted",
ScheduledStatusID: "",
Blurhash: "LARysgM_IU_3~pD%M_Rj_39FIAt6",
Blurhash: "L3Q9_@4n9E?axW4mD$Mx~q00Di%L",
Processing: 2,
File: gtsmodel.File{
Path: "062G5WYKY35KKD12EMSM3F8PJ8/attachment/original/01PFPMWK2FF0D9WMHEJHR07C3R.jpg",
@ -1120,11 +1122,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 19310,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "062G5WYKY35KKD12EMSM3F8PJ8/attachment/small/01PFPMWK2FF0D9WMHEJHR07C3R.jpg",
ContentType: "image/jpeg",
FileSize: 20395,
URL: "http://localhost:8080/fileserver/062G5WYKY35KKD12EMSM3F8PJ8/header/small/01PFPMWK2FF0D9WMHEJHR07C3R.jpg",
RemoteURL: "http://fossbros-anonymous.io/attachments/small/a499f55b-2d1e-4acd-98d2-1ac2ba6d79b9.jpg",
Path: "062G5WYKY35KKD12EMSM3F8PJ8/attachment/small/01PFPMWK2FF0D9WMHEJHR07C3R.webp",
ContentType: "image/webp",
FileSize: 9128,
URL: "http://localhost:8080/fileserver/062G5WYKY35KKD12EMSM3F8PJ8/header/small/01PFPMWK2FF0D9WMHEJHR07C3R.webp",
},
Avatar: util.Ptr(false),
Header: util.Ptr(true),
@ -1158,7 +1159,7 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
},
AccountID: "01FHMQX3GAABWSM0S2VZEC2SWC",
Description: "Photograph of a sloth, Public Domain.",
Blurhash: "LNEC{|w}0K9GsEtPM|j[NFbHoeof",
Blurhash: "LKE3VIw}0KD%a2o{M|t7NFWps:t7",
Processing: 2,
File: gtsmodel.File{
Path: "01FHMQX3GAABWSM0S2VZEC2SWC/attachment/original/01HE7Y3C432WRSNS10EZM86SA5.jpg",
@ -1166,10 +1167,10 @@ func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
FileSize: 5450054,
},
Thumbnail: gtsmodel.Thumbnail{
Path: "01FHMQX3GAABWSM0S2VZEC2SWC/attachment/small/01HE7Y3C432WRSNS10EZM86SA5.jpg",
ContentType: "image/jpeg",
FileSize: 50820,
URL: "http://localhost:8080/fileserver/01FHMQX3GAABWSM0S2VZEC2SWC/attachment/small/01HE7Y3C432WRSNS10EZM86SA5.jpg",
Path: "01FHMQX3GAABWSM0S2VZEC2SWC/attachment/small/01HE7Y3C432WRSNS10EZM86SA5.webp",
ContentType: "image/webp",
FileSize: 42208,
URL: "http://localhost:8080/fileserver/01FHMQX3GAABWSM0S2VZEC2SWC/attachment/small/01HE7Y3C432WRSNS10EZM86SA5.webp",
},
Avatar: util.Ptr(false),
Header: util.Ptr(false),
@ -1354,39 +1355,39 @@ func newTestStoredAttachments() map[string]filenames {
return map[string]filenames{
"admin_account_status_1_attachment_1": {
Original: "welcome-original.jpg",
Small: "welcome-small.jpg",
Small: "welcome-small.webp",
},
"local_account_1_status_4_attachment_1": {
Original: "trent-original.gif",
Small: "trent-small.jpg",
Small: "trent-small.webp",
},
"local_account_1_status_4_attachment_2": {
Original: "cowlick-original.mp4",
Small: "cowlick-small.jpeg",
Small: "cowlick-small.webp",
},
"local_account_1_unattached_1": {
Original: "ohyou-original.jpg",
Small: "ohyou-small.jpg",
Small: "ohyou-small.webp",
},
"local_account_1_avatar": {
Original: "zork-original.jpg",
Small: "zork-small.jpg",
Small: "zork-small.webp",
},
"local_account_1_header": {
Original: "team-fortress-original.jpg",
Small: "team-fortress-small.jpg",
Small: "team-fortress-small.webp",
},
"local_account_1_status_8_attachment_1": {
Original: "ghosts-original.mp3",
Small: "ghosts-small.jpg",
Small: "ghosts-small.webp",
},
"remote_account_1_status_1_attachment_1": {
Original: "thoughtsofdog-original.jpg",
Small: "thoughtsofdog-small.jpg",
Small: "thoughtsofdog-small.webp",
},
"remote_account_2_status_1_attachment_1": {
Original: "sloth-original.jpg",
Small: "sloth-small.jpg",
Small: "sloth-small.webp",
},
}
}