Videos: Add bitrate and pixel format to ffmpeg transcoding params #703
This commit is contained in:
parent
0bd7ebeee3
commit
2671edf982
|
@ -71,8 +71,6 @@ func GetVideo(router *gin.RouterGroup) {
|
|||
|
||||
return
|
||||
} else if f.FileCodec != string(videoType.Codec) {
|
||||
log.Debugf("video: transcoding %s from %s to avc", txt.Quote(f.FileName), txt.Quote(f.FileCodec))
|
||||
|
||||
start := time.Now()
|
||||
conv := service.Convert()
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
@ -302,15 +303,34 @@ func (c *Convert) ToJpeg(f *MediaFile) (*MediaFile, error) {
|
|||
return NewMediaFile(jpegName)
|
||||
}
|
||||
|
||||
// AvcBitrate returns the ideal AVC encoding bitrate in megabits per second.
|
||||
func (c *Convert) AvcBitrate(f *MediaFile) string {
|
||||
if f == nil {
|
||||
return "8M"
|
||||
}
|
||||
|
||||
bitrate := int(math.Round(float64(f.Width()*f.Height()*15) / 1000000))
|
||||
|
||||
if bitrate <= 0 {
|
||||
return "8M"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%dM", bitrate)
|
||||
}
|
||||
|
||||
// AvcConvertCommand returns the command for converting video files to MPEG-4 AVC.
|
||||
func (c *Convert) AvcConvertCommand(f *MediaFile, avcName string) (result *exec.Cmd, useMutex bool, err error) {
|
||||
if f.IsVideo() {
|
||||
// Don't transcode more than one video at the same time.
|
||||
useMutex = true
|
||||
|
||||
format := "format=yuv420p"
|
||||
result = exec.Command(
|
||||
c.conf.FFmpegBin(),
|
||||
"-i", f.FileName(),
|
||||
"-c:v", c.conf.FFmpegCodec(),
|
||||
"-vf", format,
|
||||
"-b:v", c.AvcBitrate(f),
|
||||
"-f", "mp4",
|
||||
avcName,
|
||||
)
|
||||
|
|
|
@ -244,3 +244,73 @@ func TestConvert_Start(t *testing.T) {
|
|||
|
||||
assert.NotEqual(t, oldHash, newHash, "Fingerprint of old and new JPEG file must not be the same")
|
||||
}
|
||||
|
||||
func TestConvert_AvcBitrate(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
convert := NewConvert(conf)
|
||||
|
||||
t.Run("8M", func(t *testing.T) {
|
||||
fileName := filepath.Join(conf.ExamplesPath(), "gopher-video.mp4")
|
||||
|
||||
assert.Truef(t, fs.FileExists(fileName), "input file does not exist: %s", fileName)
|
||||
|
||||
mf, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "8M", convert.AvcBitrate(mf))
|
||||
})
|
||||
|
||||
t.Run("20M", func(t *testing.T) {
|
||||
fileName := filepath.Join(conf.ExamplesPath(), "gopher-video.mp4")
|
||||
|
||||
assert.Truef(t, fs.FileExists(fileName), "input file does not exist: %s", fileName)
|
||||
|
||||
mf, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mf.width = 1280
|
||||
mf.height = 1024
|
||||
|
||||
assert.Equal(t, "20M", convert.AvcBitrate(mf))
|
||||
})
|
||||
|
||||
t.Run("31M", func(t *testing.T) {
|
||||
fileName := filepath.Join(conf.ExamplesPath(), "gopher-video.mp4")
|
||||
|
||||
assert.Truef(t, fs.FileExists(fileName), "input file does not exist: %s", fileName)
|
||||
|
||||
mf, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mf.width = 1920
|
||||
mf.height = 1080
|
||||
|
||||
assert.Equal(t, "31M", convert.AvcBitrate(mf))
|
||||
})
|
||||
|
||||
t.Run("133M", func(t *testing.T) {
|
||||
fileName := filepath.Join(conf.ExamplesPath(), "gopher-video.mp4")
|
||||
|
||||
assert.Truef(t, fs.FileExists(fileName), "input file does not exist: %s", fileName)
|
||||
|
||||
mf, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mf.width = 4096
|
||||
mf.height = 2160
|
||||
|
||||
assert.Equal(t, "133M", convert.AvcBitrate(mf))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user