Skip to content

Commit

Permalink
Merge pull request #293 from bcc-code/fix/wrong-data-bmm
Browse files Browse the repository at this point in the history
Prevent super short chapters from interfering
  • Loading branch information
KillerX authored Aug 15, 2024
2 parents 307334e + c51d863 commit 1019b54
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 30 deletions.
88 changes: 62 additions & 26 deletions services/vidispine/chapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,74 @@ func TestMergeTerseTimecodes(t *testing.T) {
assert.Equal(t, expected, result)
}

func Test_GetChapterMetaForClips(t *testing.T) {
clips := []*Clip{
// This is an edge case where the annotations overlap by a few frames
func Test_GetChapterMetaForClips_Overlapping(t *testing.T) {
if os.Getenv("VIDISPINE_BASE_URL") == "" {
t.Skip("VIDISPINE_BASE_URL is not set")
}

// The important thing here is the VXID of the main file (not the audio file),
// together with the in and out points of the clip.
//
// The situation is that two annotations (chapters) in MB overlap by a few frames,
// making the system think that there are two chapters between the in and out point.
// While this is techinically correct, it is not what we want, if one of the "chapters"
// is very short (less than 10 seconds). At this point it is unlikely to be a real chapter and we can ignore it.
testData := [][]*Clip{
{
{
VideoFile: "/dummy/file.mp4",
InSeconds: 1420.1199999999953,
OutSeconds: 2767.439999999988,
SequenceIn: 0,
SequenceOut: 0,
AudioFiles: map[string]*AudioFile{
"nor": {
VXID: "VX-489605",
Streams: []int{2},
File: "/dummy/file.wav",
},
},
SubtitleFiles: map[string]string{},
JSONTranscriptFile: "",
VXID: "VX-489598",
},
},
{
VideoFile: "/dummy/file.mp4",
InSeconds: 1907.7599999999948,
OutSeconds: 3025.399999999994,
SequenceIn: 0,
SequenceOut: 0,
AudioFiles: map[string]*AudioFile{
"nor": {
VXID: "VX-486737",
Streams: []int{1, 2},
File: "/dummy/file.wav",
{
VideoFile: "/dummy/file.mp4",
InSeconds: 3750.9199999999983,
OutSeconds: 3906.87999999999,
SequenceIn: 0,
SequenceOut: 0,
AudioFiles: map[string]*AudioFile{
"nor": {
VXID: "VX-489605",
Streams: []int{2},
File: "/dummy/file.wav",
},
},
SubtitleFiles: map[string]string{},
JSONTranscriptFile: "",
VXID: "VX-489598",
},
SubtitleFiles: map[string]string{},
JSONTranscriptFile: "",
VXID: "VX-486737",
},
}

client := vsapi.NewClient(
os.Getenv("VIDISPINE_BASE_URL"),
os.Getenv("VIDISPINE_USERNAME"),
os.Getenv("VIDISPINE_PASSWORD"),
)
out, err := GetChapterMetaForClips(client, clips)
assert.NoError(t, err)
assert.NotEmpty(t, out)
for _, clips := range testData {

for i, chapter := range out {
assert.GreaterOrEqual(t, len(chapter.Meta.Terse["title"]), 1, "Chapter in loop iteration %d has no title", i)
}
client := vsapi.NewClient(
os.Getenv("VIDISPINE_BASE_URL"),
os.Getenv("VIDISPINE_USERNAME"),
os.Getenv("VIDISPINE_PASSWORD"),
)
out, err := GetChapterMetaForClips(client, clips)
assert.NoError(t, err)
assert.NotEmpty(t, out)
assert.Len(t, out, 1)

for i, chapter := range out {
assert.GreaterOrEqual(t, len(chapter.Meta.Terse["title"]), 1, "Chapter in loop iteration %d has no title", i)
}
}
}
18 changes: 14 additions & 4 deletions services/vidispine/vsapi/chapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,36 @@ func (c *Client) GetChapterMeta(itemVXID string, inTc, outTc float64) (map[strin
outClips := map[string]*MetadataResult{}

for key, clip := range clips {
duration := 0.0

for _, field := range clip.Terse {
for _, value := range field {
trimTimecodesToBeWithinRange(value, inTc, outTc)
duration = trimTimecodesToBeWithinRange(value, inTc, outTc)
}
}

if duration < 10.0 {
// If the trimmed chapter duration is < 10s we don't consider it a valid chapter
continue
}

outClips[key] = clip
}

return outClips, nil
}

// trimTimecodesToBeWithinRange ensures that the timecodes are within the clip range
func trimTimecodesToBeWithinRange(value *MetadataField, inTc, outTc float64) {
if valueStart, _ := vscommon.TCToSeconds(value.Start); valueStart < inTc {
func trimTimecodesToBeWithinRange(value *MetadataField, inTc, outTc float64) float64 {
valueStart, _ := vscommon.TCToSeconds(value.Start)
if valueStart < inTc {
value.Start = fmt.Sprintf("%.0f@PAL", inTc*25)
}

if valueEnd, _ := vscommon.TCToSeconds(value.End); valueEnd > outTc {
valueEnd, _ := vscommon.TCToSeconds(value.End)
if valueEnd > outTc {
value.End = fmt.Sprintf("%.0f@PAL", outTc*25)
}

return valueEnd - valueStart
}

0 comments on commit 1019b54

Please sign in to comment.