mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] support processing of (many) more media types (#3090)
* initial work replacing our media decoding / encoding pipeline with ffprobe + ffmpeg * specify the video codec to use when generating static image from emoji * update go-storage library (fixes incompatibility after updating go-iotools) * maintain image aspect ratio when generating a thumbnail for it * update readme to show go-ffmpreg * fix a bunch of media tests, move filesize checking to callers of media manager for more flexibility * remove extra debug from error message * fix up incorrect function signatures * update PutFile to just use regular file copy, as changes are file is on separate partition * fix remaining tests, remove some unneeded tests now we're working with ffmpeg/ffprobe * update more tests, add more code comments * add utilities to generate processed emoji / media outputs * fix remaining tests * add test for opus media file, add license header to utility cmds * limit the number of concurrently available ffmpeg / ffprobe instances * reduce number of instances * further reduce number of instances * fix envparsing test with configuration variables * update docs and configuration with new media-{local,remote}-max-size variables
This commit is contained in:
148
vendor/github.com/dsoprea/go-exif/v3/common/utility.go
generated
vendored
148
vendor/github.com/dsoprea/go-exif/v3/common/utility.go
generated
vendored
@ -1,148 +0,0 @@
|
||||
package exifcommon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
var (
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
)
|
||||
|
||||
// DumpBytes prints a list of hex-encoded bytes.
|
||||
func DumpBytes(data []byte) {
|
||||
fmt.Printf("DUMP: ")
|
||||
for _, x := range data {
|
||||
fmt.Printf("%02x ", x)
|
||||
}
|
||||
|
||||
fmt.Printf("\n")
|
||||
}
|
||||
|
||||
// DumpBytesClause prints a list like DumpBytes(), but encapsulated in
|
||||
// "[]byte { ... }".
|
||||
func DumpBytesClause(data []byte) {
|
||||
fmt.Printf("DUMP: ")
|
||||
|
||||
fmt.Printf("[]byte { ")
|
||||
|
||||
for i, x := range data {
|
||||
fmt.Printf("0x%02x", x)
|
||||
|
||||
if i < len(data)-1 {
|
||||
fmt.Printf(", ")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf(" }\n")
|
||||
}
|
||||
|
||||
// DumpBytesToString returns a stringified list of hex-encoded bytes.
|
||||
func DumpBytesToString(data []byte) string {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
for i, x := range data {
|
||||
_, err := b.WriteString(fmt.Sprintf("%02x", x))
|
||||
log.PanicIf(err)
|
||||
|
||||
if i < len(data)-1 {
|
||||
_, err := b.WriteRune(' ')
|
||||
log.PanicIf(err)
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// DumpBytesClauseToString returns a comma-separated list of hex-encoded bytes.
|
||||
func DumpBytesClauseToString(data []byte) string {
|
||||
b := new(bytes.Buffer)
|
||||
|
||||
for i, x := range data {
|
||||
_, err := b.WriteString(fmt.Sprintf("0x%02x", x))
|
||||
log.PanicIf(err)
|
||||
|
||||
if i < len(data)-1 {
|
||||
_, err := b.WriteString(", ")
|
||||
log.PanicIf(err)
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// ExifFullTimestampString produces a string like "2018:11:30 13:01:49" from a
|
||||
// `time.Time` struct. It will attempt to convert to UTC first.
|
||||
func ExifFullTimestampString(t time.Time) (fullTimestampPhrase string) {
|
||||
t = t.UTC()
|
||||
|
||||
return fmt.Sprintf("%04d:%02d:%02d %02d:%02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
|
||||
}
|
||||
|
||||
// ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49" into a UTC
|
||||
// `time.Time` struct.
|
||||
func ParseExifFullTimestamp(fullTimestampPhrase string) (timestamp time.Time, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
parts := strings.Split(fullTimestampPhrase, " ")
|
||||
datestampValue, timestampValue := parts[0], parts[1]
|
||||
|
||||
// Normalize the separators.
|
||||
datestampValue = strings.ReplaceAll(datestampValue, "-", ":")
|
||||
timestampValue = strings.ReplaceAll(timestampValue, "-", ":")
|
||||
|
||||
dateParts := strings.Split(datestampValue, ":")
|
||||
|
||||
year, err := strconv.ParseUint(dateParts[0], 10, 16)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse year")
|
||||
}
|
||||
|
||||
month, err := strconv.ParseUint(dateParts[1], 10, 8)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse month")
|
||||
}
|
||||
|
||||
day, err := strconv.ParseUint(dateParts[2], 10, 8)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse day")
|
||||
}
|
||||
|
||||
timeParts := strings.Split(timestampValue, ":")
|
||||
|
||||
hour, err := strconv.ParseUint(timeParts[0], 10, 8)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse hour")
|
||||
}
|
||||
|
||||
minute, err := strconv.ParseUint(timeParts[1], 10, 8)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse minute")
|
||||
}
|
||||
|
||||
second, err := strconv.ParseUint(timeParts[2], 10, 8)
|
||||
if err != nil {
|
||||
log.Panicf("could not parse second")
|
||||
}
|
||||
|
||||
timestamp = time.Date(int(year), time.Month(month), int(day), int(hour), int(minute), int(second), 0, time.UTC)
|
||||
return timestamp, nil
|
||||
}
|
||||
|
||||
// IsTime returns true if the value is a `time.Time`.
|
||||
func IsTime(v interface{}) bool {
|
||||
|
||||
// TODO(dustin): Add test
|
||||
|
||||
return reflect.TypeOf(v) == timeType
|
||||
}
|
Reference in New Issue
Block a user