m3u8d/merge.go

136 lines
2.7 KiB
Go

package m3u8d
import (
"crypto/sha256"
"encoding/hex"
"errors"
"io"
"os"
"os/exec"
"path/filepath"
"sync"
)
type SetupFfmpeg_Resp struct {
ErrMsg string
FfmpegPath string
}
var gFfmpegExePath string
var gFfmpegExePathLocker sync.Mutex
func SetupFfmpeg() (p string, err error) {
gFfmpegExePathLocker.Lock()
defer gFfmpegExePathLocker.Unlock()
if gFfmpegExePath != "" {
return gFfmpegExePath, nil
}
ffmpegPath, err := exec.LookPath("ffmpeg")
if err != nil {
ffmpegPath, err = UnzipFfmpegToLocal(getTempDir())
if err != nil {
return "", err
}
gFfmpegExePath = ffmpegPath
return ffmpegPath, nil
}
gFfmpegExePath = ffmpegPath
return ffmpegPath, nil
}
func getTempDir() string {
dir := filepath.Join(os.TempDir(), "m3u8d")
if !isDirExists(dir) {
_ = os.MkdirAll(dir, 0777)
}
return dir
}
func mergeTsFileList_Ffmpeg(ffmpegPath string, tsFileList []string, outputMp4 string) (contentHash string, err error) {
outputMp4Temp := outputMp4 + ".tmp"
cmd := exec.Command(ffmpegPath, "-i", "-", "-acodec", "copy", "-vcodec", "copy", "-f", "mp4", outputMp4Temp)
ip, err := cmd.StdinPipe()
if err != nil {
return "", err
}
if isFileExists(outputMp4Temp) {
err = os.Remove(outputMp4Temp)
if err != nil {
return "", err
}
}
//cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
setupCmd(cmd)
err = cmd.Start()
if err != nil {
return "", err
}
for _, name := range tsFileList {
fin, err := os.Open(name)
if err != nil {
cmd.Process.Kill()
cmd.Wait()
return "", errors.New("read error: " + err.Error())
}
_, err = io.Copy(ip, fin)
if err != nil {
cmd.Process.Kill()
cmd.Wait()
fin.Close()
return "", errors.New("write error: " + err.Error())
}
fin.Close()
}
err = ip.Close()
if err != nil {
cmd.Process.Kill()
cmd.Wait()
return "", errors.New("ip.Close error: " + err.Error())
}
err = cmd.Wait()
if err != nil {
return "", err
}
err = os.Rename(outputMp4Temp, outputMp4)
if err != nil {
return "", err
}
return getFileSha256(outputMp4), nil
}
func mergeTsFileList_Raw(tsFileList []string, outputTs string) (hash string, err error) {
fout, err := os.Create(outputTs)
if err != nil {
return "", err
}
hashWriter := sha256.New()
multiW := io.MultiWriter(fout, hashWriter)
for _, tsName := range tsFileList {
var fin *os.File
fin, err = os.Open(tsName)
if err != nil {
fout.Close()
_ = os.Remove(outputTs)
return "", err
}
_, err = io.Copy(multiW, fin)
if err != nil {
fin.Close()
fout.Close()
_ = os.Remove(outputTs)
return "", err
}
fin.Close()
}
err = fout.Close()
if err != nil {
return "", err
}
tmp := hashWriter.Sum(nil)
return hex.EncodeToString(tmp[:]), nil
}