sqlite вычисления тайм-кода - PullRequest
0 голосов
/ 13 января 2020

У меня есть две таблицы, которые я экспортирую из своего набора для редактирования видео, одна ("MediaPool"), содержащая строку для каждого медиа-файла, импортированного в проект, другая ("Montage") для частей этого файла, используемых в указанном файле. c изменить. Поля, которые связаны между ними, являются MediaPool.FileName и Montage.Name, которые очень похожи (имя файла добавляет только расширение файла).

# MediaPool

Filename       | Take
---------------------------------
somefile.mp4   | Getty
file2.mov      | Associated Press
file3.mov      | Associated Press

и

# Montage

Name           | RecordIn    | RecordOut
------------------------------------------
somefile       | 01:01:01:01 | 01:01:20:19
somefile       | 01:05:15:23 | 01:05:16:10
somefile       | 01:25:19:10 | 01:30:16:04
file2          | 01:30:11:10 | 01:31:18:12
file2          | 01:40:15:22 | 01:42:21:17

таблицы, конечно, содержат гораздо больше столбцов, но имеет значение только вышеприведенное.

Только таблица «MediaPool» содержит поле «Take», которое обозначает правообладателя файла (длинная история). Он не может быть включен в экспорт "Montage". Мне нужно было рассчитать общую длительность отснятого материала, использованного каждым источником, вычитая тайм-код RecordIn из RecordOut и добавляя каждый результат. Это оказалось сложнее, чем я ожидал, так как у меня есть некоторые представления о программировании, но почти нет, когда дело доходит до SQL (sqlite в моем случае).

Мне удалось придумать следующее, который работает нормально и работает менее чем за 4 секунды. Тем не менее, из небольшого программирования, которое я сделал, оно кажется слишком длинным и очень элегантным. Есть ли более короткий способ добиться этого?

Кстати, я использую тайм-код со скоростью 25 кадров в секунду и не могу использовать LPAD в sqlite.


    SELECT 
        Source,
        SUBSTR('00' || CAST(DurationFrames/(60*60*25) AS TEXT), -2, 2) || ':' ||
        SUBSTR('00' || CAST(DurationFrames%(60*60*25)/(60*25) AS TEXT), -2, 2) || ':' ||
        SUBSTR('00' || CAST(DurationFrames%(60*60*25)%(60*25)/25 AS TEXT), -2, 2) || ':' || 
        SUBSTR('00' || CAST(DurationFrames%(60*60*25)%(60*25)%25 AS TEXT), -2, 2)
        AS DurationTC
    FROM
    (
    SELECT
        MediaPool.Take AS Source, 
        Montage.RecordIn, 
        Montage.RecordOut, 
        SUM(CAST(SUBSTR(Montage.RecordOut, 1, 2) AS INT)*3600*25 + 
            CAST(SUBSTR(Montage.RecordOut, 4, 2) AS INT)*60*25  + 
            CAST(SUBSTR(Montage.RecordOut, 7, 2) AS INT)*25 + 
            CAST(SUBSTR(Montage.RecordOut, 10, 2) AS INT) - 
            CAST(SUBSTR(Montage.RecordIn, 1, 2) AS INT)*3600*25 - 
            CAST(SUBSTR(Montage.RecordIn, 4, 2) AS INT)*60*25 - 
            CAST(SUBSTR(Montage.RecordIn, 7, 2) AS INT)*25 - 
            CAST(SUBSTR(Montage.RecordIn, 10, 2) AS INT))
        AS DurationFrames
    FROM
        MediaPool
    JOIN 
        Montage ON MediaPool.FileName LIKE '%' || Montage.Name || '%'
    GROUP BY
        Take
    ORDER BY 
        Take
    )

1 Ответ

1 голос
/ 13 января 2020

Вот упрощенный запрос, который дает те же результаты, что и вы, по вашим тестовым данным. В основном он использует printf() вместо связки строк и substr() s и использует strftime() для вычисления общего количества секунд тайм-кода часов-минут-секунд:

WITH frames AS
 (SELECT Take, sum((strftime('%s', substr(RecordOut,1,8))*25 + substr(RecordOut,10))
                 - (strftime('%s', substr(RecordIn,1,8))*25 + substr(RecordIn,10)))
                  AS DurationFrames
  FROM MediaPool
  JOIN Montage ON MediaPool.Filename LIKE Montage.Name || '.%'
  GROUP BY Take)
SELECT Take AS Source
     , printf("%02d:%02d:%02d:%02d", DurationFrames/(60*60*25),
                                     DurationFrames%(60*60*25)/(60*25),
                                     DurationFrames%(60*60*25)%(60*25)/25,
                                     DurationFrames%(60*60*25)%(60*25)%25)
                                     AS DurationTC
FROM frames
ORDER BY Take;
...