Skip to content

Instantly share code, notes, and snippets.

@panki
Created May 24, 2022 04:15
Show Gist options
  • Save panki/2c01dfda63ce8b0a31691c82a4d7bd49 to your computer and use it in GitHub Desktop.
Save panki/2c01dfda63ce8b0a31691c82a4d7bd49 to your computer and use it in GitHub Desktop.
ffmpeg split & convert
package ffmpeg
import (
"fmt"
"os"
"regexp"
"strings"
"github.com/gofrs/uuid"
)
// SplitFile splits file into parts
func SplitFile(filename string, splitBy float64, treshold float64) ([]string, error) {
format, err := GetFileFormat(filename)
if err != nil {
return nil, err
}
// Generate split points
points := splitPoints(format.StartTime, format.Duration, splitBy, treshold)
if len(points) == 0 {
// skip splitting by using 1 point greater than duration
points = append(points, format.Duration+1)
}
segments := strings.Trim(strings.Replace(fmt.Sprint(points), " ", ",", -1), "[]")
// Split file
outputFile := fmt.Sprintf("%s%s-%%04d.mp4", os.TempDir(), uuid.Must(uuid.NewV4()))
_, stderr, err := execCmd(
ffmpeg,
"-v", "info", // log level
"-y", // overwrite files
"-i", filename, // input filename
"-f", "segment", "-segment_times", segments, // split points
"-c:a", "aac", // codec
"-b:a", "64k", // bitrate
"-ar", "48000", // sample
"-map", "0:0", // TODO: map only audio streams from input to output
"-reset_timestamps", "1", // set start time of every chunk to 0
"-movflags", "+faststart", // move meta to the beginning
outputFile, // output file format
)
if err != nil {
if len(stderr) > 0 {
return nil, fmt.Errorf("ffmpeg: %s", stderr)
}
return nil, fmt.Errorf("ffmpeg: %s", err)
}
// Collect filenames from output
matches := splitOutput.FindAllStringSubmatch(string(stderr), -1)
files := []string{}
for _, m := range matches {
files = append(files, m[1])
}
if len(files) == 0 {
return nil, fmt.Errorf("Not output files")
}
return files, nil
}
func splitPoints(start float64, stop float64, length float64, treshold float64) (points []float64) {
for {
if stop-start <= length+treshold {
return
}
start += length
points = append(points, start)
}
}
var splitOutput = regexp.MustCompile("Opening '([^']+)' for writing")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment