From d4d0a1bae61748139e579ff4135dee4fbf70369c Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Thu, 17 Mar 2022 13:59:32 -0400 Subject: [PATCH] internal/cmd/cmd.go: Synchronize streams to end of first silence Detect silence by use of ffmpeg on the english language stream and substitute $seek with the value. This allows for approximate synchronization of video streams. Signed-off-by: Liam R. Howlett --- internal/cmd/cmd.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 63e3515..af3cbee 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -147,6 +147,29 @@ func (s *Store) GetCommand(multi ChannelMatcher) Command { } } +func (s *Store) GetVideoOffset(url string) (string) { + var skip int + + skip = 0; + for i := 10; i < 120; i += 20 { + ffmpeg := exec.Command("ffmpeg", "-ss", strconv.Itoa(skip), "-t", strconv.Itoa(i), "-i", url, "-map", "0:m:language:eng", "-af", "silencedetect=noise=-18dB:d=0.5", "-f","null","-") + out, err := ffmpeg.CombinedOutput() + if err != nil { + fmt.Fprintf(s.logger, "error detecting synchronization: %s\n", err) + return "0"; + } + + match := regexp.MustCompile(".* silence_end: (\\d+\\.\\d+)").FindStringSubmatch(string(out)) + if match != nil { + return strings.Split(match[0], ": ")[1] + } + skip = i - 1; + } + + fmt.Fprintf(s.logger, "error detecting synchronization: No silence_end found\n") + return "0"; +} + func (s *Store) RunCommand(cc CommandContext) error { url, err := cc.URL() if err != nil { @@ -184,6 +207,11 @@ func (s *Store) RunCommand(cc CommandContext) error { s.logger.Error("failed to convert metadata to JSON:", err) } for i := range tmpCommand { + if (strings.Contains(tmpCommand[i], "$seek")) { + offset := s.GetVideoOffset(url) + tmpCommand[i] = strings.ReplaceAll(tmpCommand[i], "$seek", offset); + } + tmpCommand[i] = strings.ReplaceAll(tmpCommand[i], "$url", url) tmpCommand[i] = strings.ReplaceAll(tmpCommand[i], "$json", string(metadataJson)) tmpCommand[i] = strings.ReplaceAll(tmpCommand[i], "$session", cc.MetaData.Session)