86 lines
1.7 KiB
Go
86 lines
1.7 KiB
Go
package ffmpeg
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
func FFProbe(fname string) (FFProbeOutput, error) {
|
|
log.Println("probe", fname)
|
|
cmd := exec.Command(
|
|
"/usr/bin/ffprobe",
|
|
"-loglevel", "error",
|
|
fname,
|
|
"-show_streams",
|
|
"-of", "json",
|
|
)
|
|
cmd.Stderr = os.Stderr
|
|
stdout, err := cmd.StdoutPipe()
|
|
if err != nil {
|
|
log.Println("Failed to pipe", err)
|
|
return FFProbeOutput{}, err
|
|
}
|
|
|
|
err = cmd.Start()
|
|
if err != nil {
|
|
log.Println("Failed start", err)
|
|
return FFProbeOutput{}, err
|
|
}
|
|
|
|
var ffout FFProbeOutput
|
|
err = json.NewDecoder(stdout).Decode(&ffout)
|
|
if err != nil {
|
|
log.Println("Failed to decode", err)
|
|
return FFProbeOutput{}, err
|
|
}
|
|
|
|
return ffout, nil
|
|
}
|
|
|
|
func FigureOutHLSCodecsParam(stream FFProbeStream) (string, error) {
|
|
// TODO: This is still very lame
|
|
var avcProfileBits = map[string]int{
|
|
"High": 0x64,
|
|
"Main": 0x4D,
|
|
"Baseline": 0x42,
|
|
}
|
|
|
|
var hevcProfileBits = map[string]int{
|
|
"Main": 1,
|
|
"Main 10": 2,
|
|
}
|
|
|
|
if stream.CodecType == "video" {
|
|
if stream.CodecName == "h264" {
|
|
//avc1.<profile_idc><constraint_set_flags><level_idc>
|
|
codecTagBytes, err := hex.DecodeString(strings.TrimPrefix(stream.CodecTag, "0x"))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return fmt.Sprintf(
|
|
"%s.%02X%02X%02X",
|
|
stream.CodecTagString,
|
|
avcProfileBits[stream.Profile],
|
|
codecTagBytes[1],
|
|
stream.Level,
|
|
), nil
|
|
}
|
|
if stream.CodecName == "hevc" {
|
|
// hvc1.<profile>.<compatibility>.<tier><level><constraints>
|
|
return fmt.Sprintf(
|
|
"%s.%d.L%d",
|
|
stream.CodecTagString,
|
|
hevcProfileBits[stream.Profile],
|
|
stream.Level,
|
|
), nil
|
|
}
|
|
|
|
}
|
|
|
|
return "", fmt.Errorf("unrecognized format")
|
|
}
|