init
This commit is contained in:
commit
fa47df6d89
22 changed files with 1724 additions and 0 deletions
120
ffmpeg/ffmpeg.go
Normal file
120
ffmpeg/ffmpeg.go
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
package ffmpeg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"stream-poc2/model"
|
||||
)
|
||||
|
||||
// EncodeChunk doesn't have the nicest function signature...
|
||||
func EncodeChunk(profileSettings model.VideoProfileSettings, nativeHeight int, preset string, origSegmentPath string, writer io.Writer) error {
|
||||
ffmpegArgs := []string{
|
||||
"-nostdin", "-hide_banner", "-loglevel", "error",
|
||||
}
|
||||
|
||||
if profileSettings.Resolution.Height != nativeHeight {
|
||||
// apply resize filter
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-hwaccel", "cuda", "-hwaccel_output_format", "cuda",
|
||||
"-i", origSegmentPath,
|
||||
"-vf", fmt.Sprintf("scale_cuda=%d:%d", profileSettings.Resolution.Width, profileSettings.Resolution.Height),
|
||||
)
|
||||
} else {
|
||||
// just load the segment
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-i", origSegmentPath,
|
||||
)
|
||||
}
|
||||
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-copyts",
|
||||
"-c:v", profileSettings.FFMpegCodec(),
|
||||
)
|
||||
if preset != "" {
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-preset", preset,
|
||||
)
|
||||
}
|
||||
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-b:v", strconv.Itoa(profileSettings.AvgBitrate), "-maxrate", strconv.Itoa(profileSettings.MaxBitrate), "-bufsize", "1M",
|
||||
"-an", // <- no audio
|
||||
"-f", "mpegts", "-mpegts_copyts", "1",
|
||||
"-",
|
||||
)
|
||||
|
||||
log.Println("exec ffmpeg args: ", ffmpegArgs)
|
||||
|
||||
cmd := exec.Command("/usr/bin/ffmpeg", ffmpegArgs...)
|
||||
cmd.Stdout = writer
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Println("Failed to run:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeSegments has the ugliest function signature no the planet
|
||||
func MakeSegments(filepath, outdir string, audioStreams []model.AudioStream) (string, []string, error) {
|
||||
segmentsVideoCSV := path.Join(outdir, "segments_video.csv")
|
||||
segmentsAudioCSV := make([]string, len(audioStreams))
|
||||
|
||||
// do slicing
|
||||
ffmpegArgs := []string{
|
||||
"-nostdin", "-hide_banner", "-loglevel", "error",
|
||||
"-i", filepath,
|
||||
// video stream
|
||||
"-c:v", "copy", "-an",
|
||||
"-f", "ssegment", "-segment_format", "mpegts", "-segment_list", segmentsVideoCSV,
|
||||
"-segment_list_type", "csv", "-segment_time", strconv.Itoa(SlicerTargetDurationSec), path.Join(outdir, "video", "s%d.ts"),
|
||||
}
|
||||
|
||||
for i, audioStream := range audioStreams {
|
||||
csvName := path.Join(outdir, fmt.Sprintf("segments_audio_%d.csv", audioStream.Index))
|
||||
segmentsAudioCSV[i] = csvName
|
||||
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
// audio streams (encode to mp3)
|
||||
"-vn", "-map", fmt.Sprintf("0:a:%d", i),
|
||||
)
|
||||
|
||||
if audioStream.Codec != "mp3" {
|
||||
// mp3 always works
|
||||
// TODO: This does not update the stream info in the metadata !!!
|
||||
log.Println("Transcoding audio to mp3 for stream ", audioStream.Index)
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-c:a", "libmp3lame", "-q:a", "0",
|
||||
)
|
||||
} else {
|
||||
log.Println("Not transcoding audio as it is already mp3 for stream ", audioStream.Index)
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-c:a", "copy",
|
||||
)
|
||||
}
|
||||
|
||||
ffmpegArgs = append(ffmpegArgs,
|
||||
"-f", "ssegment", "-segment_format", "mpegts", "-segment_list", csvName,
|
||||
"-segment_list_type", "csv", "-segment_time", strconv.Itoa(SlicerTargetDurationSec), path.Join(outdir, "audio", strconv.Itoa(audioStream.Index), "s%d.ts"),
|
||||
)
|
||||
}
|
||||
|
||||
cmd := exec.Command("/usr/bin/ffmpeg", ffmpegArgs...)
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Println("failed to segment:", err)
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return segmentsVideoCSV, segmentsAudioCSV, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue