Использование тега CFFILE Coldfusion для отслеживания журнала прогресса из FFMpeg

Я хочу узнать, как использовать тег CFFILE из ColdFusion для чтения содержимого текстового файла. В моем случае этот текстовый файл представляет собой журнал прогресса, который генерируется FFMpeg при перекодировании медиа-файла. Я хочу написать скрипт ColdFusion, который будет периодически опрашивать журнал прогресса, пока журнал не покажет, что FFMpeg завершил операцию транскодирования. На стороне клиента я могу затем использовать Ajax для запуска этого скрипта ColdFusion и показать пользователю "процент выполненных работ", пока FFMpeg выполняет свою работу.

Я получил FFMpeg, чтобы сгенерировать файл журнала, используя новый флаг "прогресс", который теперь поддерживают последние версии FFMpeg. Ниже я покажу вам, как использовать этот флаг, а также сгенерированный вывод в файле журнала.

Вот команда FFMpeg:

ffmpeg -i c:\my_original_file.ogg c:\my_converted_file.mp3 -progress c:\my_progress.txt

Приведенная выше команда заставит FFMpeg сгенерировать файл журнала с именем my_progress.txt.

Вот что он генерирует в файле журнала:

total_size=206150
out_time_ms=51410044
out_time=00:00:51.410044
dup_frames=0
drop_frames=0
progress=continue

Вышеуказанные 6 строк генерируются многократно в файле журнала с увеличением значений.

total_size=206150
out_time_ms=51410044
out_time=00:00:51.410044
dup_frames=0
drop_frames=0
progress=continue
total_size=412413
out_time_ms=102975756
out_time=00:01:42.975756
dup_frames=0
drop_frames=0
progress=continue
total_size=618363
out_time_ms=154463111
out_time=00:02:34.463111
dup_frames=0
drop_frames=0
progress=continue
total_size=824939
out_time_ms=206107189
out_time=00:03:26.107189
dup_frames=0
drop_frames=0
progress=continue

Наконец, когда работа завершается, последний блок из 6 строк является последним в файле журнала. Обратите внимание на "progress = end" в последней строке:

total_size=9725902
out_time_ms=2431348011
out_time=00:40:31.348011
dup_frames=0
drop_frames=0
progress=end

Я хочу написать скрипт Coldfusion, использующий тег CFFILE, чтобы читать только последние 6 строк файла (независимо от его размера) и делать это каждый раз, когда скрипт вызывается браузером через Ajax. Наконец, мне нужно разобрать значения в этих строках в переменные, чтобы я мог вернуть некоторые данные вызывающей стороне.

Я исследовал индикаторы выполнения для FFMpeg, но они написаны на PHP, что сложно для меня, и, кроме того, они анализируют старые отформатированные версии файлов журналов FFMpeg, и я хотел бы использовать вышеупомянутое более новое форматирование. Может кто-нибудь, пожалуйста, помогите?

2 ответа

Решение

Получить последние шесть строк tail будет быстрее, поскольку он работает в обратном направлении и загружает только то, что вы просите (вместо того, чтобы читать весь файл, а затем циклически проходить по нему). Очевидно, что он также будет использовать меньше памяти, независимо от размера файла.

<cfexecute
    name      = "tail"
    arguments = "--lines=6 #Filename#"
    timeout   = 30
    variable  = "LastSixLines"
    />

<cfset Data = {} />
<cfloop index="CurLine" array=#LastSixLines.trim().split('\n')# >
    <cfset Data[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') />
</cfloop>


Поскольку вы, кажется, находитесь в Windows, вам, вероятно, нужно установить tail (он предустановлен для Linux и MacOS). Простейшим вариантом получить его будет MSYS, который у вас уже может быть в зависимости от того, какое другое программное обеспечение вы используете - например, Git для Windows использует MSYS и имеет tail.exe в своей папке bin.

В этом случае вторая строка выше изменится на что-то вроде:

    name      = "C:/Program Files/Git/bin/tail"

Если вам нужен код для работы в нескольких системах, вы можете сделать эту часть переменной (или поместить соответствующий каталог в системный PATH, чтобы его можно было вызывать из любого места).

Это прочитает ваш файл и создаст структуру с последними 6 строками.

<cffile action="read" file="myfile.txt" variable="myfile">

<cfoutput>
    <cfset linecount = listlen(myfile,chr(10))>
    #linecount# lines

    <cfset count = 0>
    <cfset stData = {}>
    <cfloop list="#myfile#" index="i" delimiters="#chr(10)#">
        <cfset count++>
        <cfif count GT linecount - 6><!--- we only care about the last 6 lines --->
            #i#<Br>
            <cfset stData[listfirst(i,'=')] = listlast(i,'=')><!--- add data to stData --->
        </cfif>
    </cfloop>
</cfoutput>
<cfdump var="#stData#">

Приведенный выше код выведет необработанные данные из текстового файла и создаст структуру на основе = быть разделителем

Вы также можете сохранить свой файл в массиве и вытащить последние 6 строк, как показано ниже. Этот параметр примерно в 2 раза быстрее с небольшими файлами (<200 тыс. Строк), но по мере увеличения размера файла эти два параметра становятся практически идентичными, а затем первый вариант становится быстрее примерно на 1 млн. Строк.

<cffile action="read" file="c:\ColdFusion10\cfusion\wwwroot\myfile.txt" variable="myfile">

<cfset filearray = listToArray(myfile,chr(10))>
<cfset linecount = arrayLen(filearray)>
<cfset stData = {}>
<cfloop from="0" to="5" index="i">
   <cfset stData[listfirst(filearray[linecount - i],'=')] = listlast(filearray[linecount - i],'=')>
</cfloop>

Другие вопросы по тегам