Skip to content

Interpreting query results

Sergiu Ciumac edited this page Dec 23, 2021 · 1 revision

Query results

After you've issued a query, an AVQueryResult object is returned from the QueryCommand. The object will contain separate Audio and Video properties of QueryResult type. You can deconstruct it the following way:

public async Task Query(string path)
{
    var (audio, video) = await QueryCommandBuilder.Instance
        .BuildQueryCommand()
        .From(path, MediaType.Audio | MediaType.Video)
        .UsingServices(modelService, mediaService)
        .Query();

    OutputMatches(audio?.ResultEntries, MediaType.Audio);
    OutputMatches(video?.ResultEntries, MediaType.Video);
}

public void OutputMatches(IEnumerable<ResultEntry>? results, MediaType mediaType)
{
    foreach (var resultEntry in results ?? Enumerable.Empty<ResultEntry>())
    {
        if (resultEntry.Confidence > 0.15)
        {
            Console.WriteLine($"Matched ${resultEntry.Track.Id} on media type {mediaType} query, confidence {resultEntry.Confidence:0.00}.");
            Console.WriteLine($"Relative track coverage {resultEntry.TrackRelativeCoverage:0.00}");
            Console.WriteLine($"Relative query coverage {resultEntry.QueryRelativeCoverage:0.00}");
            OutputCoverage(resultEntry.Coverage);
            Console.WriteLine("\n");
        }
    } 
}

private void OutputCoverage(Coverage coverage)
{
    Console.WriteLine($"Track discrete coverage length {coverage.TrackDiscreteCoverageLength}, with detected {coverage.TrackGaps.Count()} gaps of length {coverage.TrackGapsCoverageLength}");
    Console.WriteLine($"Query discrete coverage length {coverage.QueryDiscreteCoverageLength}, with detected {coverage.QueryGaps.Count()} gaps");
}

The QueryResult object will contain aggregated result entries (i.e., instances of ResultEntry class), each one corresponding to a different matched track.

Query result details

Every ResultEntry object will contain the following information:

  • Track - a matched track from the datastore
  • QueryMatchLength - returns how many query seconds matched the resulting track
  • QueryMatchStartsAt - returns time position where the resulting track started to match in the query
  • TrackMatchStartsAt - returns time position where the query started to match in the resulting track
  • TrackStartsAt - returns an approximation where does the matched track starts, always relative to the query
  • Confidence - returns a value between [0, 1]. A value below 0.15 is most probably a false positive. A value bigger than 0.15 is very likely to be an exact match. For good audio quality queries, you can expect to get a confidence > 0.5.
  • MatchedAt - returns timestamp shows at what time did the match occurred. Useful for real-time queries.

Coverage object describing all the details about the match

As an example think about Track A matched with the query in the following regions (a, b and c):

Track A        -------------------------------------------
                  a          b                   c
                        x             y
Matched        -------     ------           --------------
Time (sec)     0     5     7   10           15          30

Permitted Gap is a query configuration parameter, default value = 2.5.

  • TrackCoverageLength = a + b + c = 5 + 3 + 15 = 23
  • TrackCoverageWithPermittedGapsLength = a + x + b + c = 5 + 2 + 3 + 15 = 25
  • TrackDiscreteCoverageLength = a + x + b + y + c = 5 + 2 + 3 + 5 + 15 = 30
  • Gap x is ignored since it is smaller than permitted gap length (i.e., 2 seconds < 2.5 seconds)
  • TrackGapsCoverageLength = 5 seconds
  • TrackGaps - will contain one entry of Gap class with Start = 10, End = 15.