Использование тега 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>