Created
May 24, 2022 04:15
-
-
Save panki/2c01dfda63ce8b0a31691c82a4d7bd49 to your computer and use it in GitHub Desktop.
ffmpeg split & convert
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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