У меня есть функция:
public List<VideoInfo> FindNearestVideosByDuration(string folderPath, double eventStart, double eventLength, List<VideoInfo> VideosOnTimeline)
{
    List<VideoInfo> videoInfos = folderAnalizator.GetVideoInfoFromFolder(folderPath)
        .Except(VideosOnTimeline, new VideoInfoNameComparer())
        .ToList();

    videoInfos = videoInfos.OrderByDescending(v => v.DurationInMilliseconds).ToList();

    Dictionary<double, List<VideoInfo>> dp = new Dictionary<double, List<VideoInfo>> { { 0, new List<VideoInfo>() } };

    foreach (var video in videoInfos)
    {
        var newDp = new Dictionary<double, List<VideoInfo>>(dp);

        foreach (var entry in dp)
        {
            double newDuration = entry.Key + video.DurationInMilliseconds;

            if (newDuration <= eventLength && !newDp.ContainsKey(newDuration))
            {
                var newList = new List<VideoInfo>(entry.Value) { video };

                int generalVideo = video.GeneralVideo;

                // Находим "близкие" видео на таймлайне (в пределах 19000 мс)
                var nearbyVideos = VideosOnTimeline
                    .Where(v => v.GeneralVideo == generalVideo &&
                                 (Math.Abs(v.StartOnTimeline - eventStart) <= 19000 ||
                                 Math.Abs(v.EndOnTimeline - (eventStart + eventLength)) <= 19000)
                    .ToList();

                // Вычисляем суммарную длительность "близких" видео
                double totalNearbyDuration = nearbyVideos.Sum(v => v.DurationInMilliseconds);

                // Вычисляем суммарную длительность видео в новом наборе
                double totalNewListDuration = newList
                    .Where(v => v.GeneralVideo == generalVideo)
                    .Sum(v => v.DurationInMilliseconds);

                // Общая длительность
                double totalGeneralDuration = totalNearbyDuration + totalNewListDuration;

                // Проверяем, все ли видео свободны от авторских прав
                bool allCopyrightFree = newList.All(v => v.CopyrightFree);

                if ((totalGeneralDuration <= 19000 || allCopyrightFree) && newDuration <= eventLength)
                {
                    newDp[newDuration] = newList;
                }
            }
        }

        dp = newDp;
    }

    var bestMatch = dp.OrderByDescending(x => x.Key).FirstOrDefault().Value;

    if (bestMatch != null)
    {
        bestMatch = bestMatch.OrderBy(v => v.VideoSegment).ToList();

        double currentStart = eventStart;
        foreach (var video in bestMatch)
        {
            string Info = $"{video.Name}\n";
            video.StartOnTimeline = currentStart;
            video.LengthOnTimeline = video.DurationInMilliseconds;
            Info += $"Start: {video.StartOnTimeline}\nLength: {video.LengthOnTimeline}\nDuration: {video.DurationInMilliseconds}";
            MessageBox.Show(Info);
            video.EndOnTimeline = currentStart + video.LengthOnTimeline;
            VideosOnTimeline.Add(video);
            currentStart = video.EndOnTimeline;
        }
    }

    return bestMatch ?? new List<VideoInfo>();
}

Я проверил функцию на следующем примере:
eventStart = 0, eventLength = 23540.
videosOnTimeline - нету.
В указанной папке были 3 видео:
Видео А: GeneralVideo = 1, длительность 15840 мс, CopyrightFree = True
Видео Б: GeneralVideo = 1, длительность 28350 мс, CopyrightFree = True
Видео В: GeneralVideo = 2, длительность 32840 мс, CopyrightFree = False

Функция добавила на таймлайн только Видео А. Но почему так? В таком случае она должна была найти более подходящее по длительности видео, которым является Видео Б, ведь абсолютная разница его длительности с eventLength составляет 4810, тогда как у Видео А разница 7700. Исправь код в соответствии с этим.