Ver código fonte

调整字幕是否匹配视频判断的细节

Signed-off-by: allan716 <[email protected]>
allan716 3 anos atrás
pai
commit
086af3854c

+ 2 - 2
TestCode/test_statistics_subs_score.go

@@ -209,7 +209,7 @@ func statistics_subs_score(baseAudioFileFPath, baseSubFileFPath, subSearchRootPa
 func statistics_subs_score_is_match(videoFPath, subSearchRootPath string) {
 
 	s := sub_timeline_fixer.NewSubTimelineFixerHelperEx(log_helper.GetLogger4Tester(), *settings.NewTimelineFixerSettings())
-	bok, audioVADInfos, infoBase, err := s.IsVideoCanExportSubtitleAndAudio(videoFPath)
+	bok, ffmpegInfo, audioVADInfos, infoBase, err := s.IsVideoCanExportSubtitleAndAudio(videoFPath)
 	if err != nil {
 		return
 	}
@@ -260,7 +260,7 @@ func statistics_subs_score_is_match(videoFPath, subSearchRootPath string) {
 				return nil
 			}
 
-			bok, audioScore, audioOffset, subScore, subOffset, err := s.IsMatchBySubFile(audioVADInfos, infoBase, path, 40000, 2)
+			bok, audioScore, audioOffset, subScore, subOffset, err := s.IsMatchBySubFile(ffmpegInfo, audioVADInfos, infoBase, path, 40000, 2)
 			if err != nil {
 				return nil
 			}

+ 31 - 0
pkg/ffmpeg_helper/ffmpeg_helper.go

@@ -7,6 +7,7 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
+	"strconv"
 
 	"github.com/allanpk716/ChineseSubFinder/pkg/types/common"
 
@@ -96,6 +97,8 @@ func (f *FFMPEGHelper) GetFFMPEGInfo(videoFileFullPath string, exportType Export
 		return false, nil, err
 	}
 
+	ffMPEGInfo.Duration = f.getVideoDuration(videoFileFullPath)
+
 	// 判断这个视频是否已经导出过内置的字幕和音频文件了
 	if ffMPEGInfo.IsExported(exportType) == false {
 		// 说明缓存不存在,需要导出,这里需要注意,如果导出失败了,这个文件夹要清理掉
@@ -644,6 +647,34 @@ func (f FFMPEGHelper) isSupportSubCodecName(name string) bool {
 	}
 }
 
+func (f FFMPEGHelper) getVideoDuration(videoFileFullPath string) float64 {
+
+	const args = "-v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i"
+	cmdArgs := strings.Fields(args)
+	cmdArgs = append(cmdArgs, videoFileFullPath)
+	cmd := exec.Command("ffprobe", cmdArgs...)
+	buf := bytes.NewBufferString("")
+	//指定输出位置
+	cmd.Stderr = buf
+	cmd.Stdout = buf
+	err := cmd.Start()
+	if err != nil {
+		return 0
+	}
+	err = cmd.Wait()
+	if err != nil {
+		return 0
+	}
+
+	// 字符串转 float64
+	durationStr := strings.TrimSpace(buf.String())
+	duration, err := strconv.ParseFloat(durationStr, 32)
+	if err != nil {
+		return 0
+	}
+	return duration
+}
+
 const (
 	codecTypeSub   = "subtitle"
 	codecTypeAudio = "audio"

+ 1 - 0
pkg/ffmpeg_helper/ffmpeg_info.go

@@ -17,6 +17,7 @@ import (
 type FFMPEGInfo struct {
 	log              *logrus.Logger
 	VideoFullPath    string                // 视频文件的路径
+	Duration         float64               // 视频的时长
 	AudioInfoList    []AudioInfo           // 内置音频列表
 	SubtitleInfoList []SubtitleInfo        // 内置字幕列表
 	ExternalSubInfos []*subparser.FileInfo // 外置字幕列表

+ 15 - 10
pkg/logic/sub_timeline_fixer/SubTimelineFixerHelperEx.go

@@ -220,20 +220,20 @@ func (s SubTimelineFixerHelperEx) ProcessByAudioFile(baseAudioFileFPath, srcSubF
 	return s.ProcessByAudioVAD(audioVADInfos, infoSrc)
 }
 
-func (s SubTimelineFixerHelperEx) IsVideoCanExportSubtitleAndAudio(videoFileFullPath string) (bool, []vad.VADInfo, *subparser.FileInfo, error) {
+func (s SubTimelineFixerHelperEx) IsVideoCanExportSubtitleAndAudio(videoFileFullPath string) (bool, *ffmpeg_helper.FFMPEGInfo, []vad.VADInfo, *subparser.FileInfo, error) {
 
 	// 先尝试获取内置字幕的信息
 	bok, ffmpegInfo, err := s.ffmpegHelper.GetFFMPEGInfo(videoFileFullPath, ffmpeg_helper.SubtitleAndAudio)
 	if err != nil {
-		return false, nil, nil, err
+		return false, nil, nil, nil, err
 	}
 	if bok == false {
-		return false, nil, nil, nil
+		return false, nil, nil, nil, nil
 	}
 	// ---------------------------------------------------------------------------------------
 	// 音频
 	if len(ffmpegInfo.AudioInfoList) <= 0 {
-		return false, nil, nil, nil
+		return false, nil, nil, nil, nil
 	}
 	audioVADInfos, err := vad.GetVADInfoFromAudio(vad.AudioInfo{
 		FileFullPath: ffmpegInfo.AudioInfoList[0].FullPath,
@@ -241,12 +241,12 @@ func (s SubTimelineFixerHelperEx) IsVideoCanExportSubtitleAndAudio(videoFileFull
 		BitDepth:     16,
 	}, true)
 	if err != nil {
-		return false, nil, nil, err
+		return false, nil, nil, nil, err
 	}
 	// ---------------------------------------------------------------------------------------
 	// 字幕
 	if len(ffmpegInfo.SubtitleInfoList) <= 0 {
-		return false, nil, nil, nil
+		return false, nil, nil, nil, nil
 	}
 	// 使用内置的字幕进行时间轴的校正,这里需要考虑一个问题,内置的字幕可能是有问题的(先考虑一种,就是字幕的长度不对,是一小段的)
 	// 那么就可以比较多个内置字幕的大小选择大的去使用
@@ -264,17 +264,17 @@ func (s SubTimelineFixerHelperEx) IsVideoCanExportSubtitleAndAudio(videoFileFull
 	baseSubFPath := ffmpegInfo.SubtitleInfoList[index.(int)].FullPath
 	bFind, infoBase, err := s.subParserHub.DetermineFileTypeFromFile(baseSubFPath)
 	if err != nil {
-		return false, nil, nil, err
+		return false, nil, nil, nil, err
 	}
 	if bFind == false {
-		return false, nil, nil, nil
+		return false, nil, nil, nil, nil
 	}
 	// ---------------------------------------------------------------------------------------
 
-	return true, audioVADInfos, infoBase, nil
+	return true, ffmpegInfo, audioVADInfos, infoBase, nil
 }
 
-func (s SubTimelineFixerHelperEx) IsMatchBySubFile(audioVADInfos []vad.VADInfo, infoBase *subparser.FileInfo, srcSubFileFPath string, minScore float64, offsetRange float64) (bool, float64, float64, float64, float64, error) {
+func (s SubTimelineFixerHelperEx) IsMatchBySubFile(ffmpegInfo *ffmpeg_helper.FFMPEGInfo, audioVADInfos []vad.VADInfo, infoBase *subparser.FileInfo, srcSubFileFPath string, minScore float64, offsetRange float64) (bool, float64, float64, float64, float64, error) {
 
 	bFind, srcBase, err := s.subParserHub.DetermineFileTypeFromFile(srcSubFileFPath)
 	if err != nil {
@@ -311,6 +311,11 @@ func (s SubTimelineFixerHelperEx) IsMatchBySubFile(audioVADInfos []vad.VADInfo,
 	if math.Abs(pipeResultMaxAudio.GetOffsetTime()-pipeResultMaxSub.GetOffsetTime()) > offsetRange {
 		return false, pipeResultMaxAudio.Score, pipeResultMaxAudio.GetOffsetTime(), pipeResultMaxSub.Score, pipeResultMaxSub.GetOffsetTime(), nil
 	}
+	// ---------------------------------------------------------------------------------------
+	// 待判断的字幕的时间长度要小于等于视频的总长度
+	if float64(srcBase.GetEndTime().Second()) > ffmpegInfo.Duration {
+		return false, pipeResultMaxAudio.Score, pipeResultMaxAudio.GetOffsetTime(), pipeResultMaxSub.Score, pipeResultMaxSub.GetOffsetTime(), nil
+	}
 	return true, pipeResultMaxAudio.Score, pipeResultMaxAudio.GetOffsetTime(), pipeResultMaxSub.Score, pipeResultMaxSub.GetOffsetTime(), nil
 }