使用Coldfusion的CFFILE标记来监视FFMpeg的进度日志

时间:2013-05-04 01:08:29

标签: ajax coldfusion ffmpeg cffile

我想学习如何使用ColdFusion中的CFFILE标签来读取文本文件的内容。在我的例子中,该文本文件是FFMpeg在对媒体文件进行转码时生成的进度日志。我想编写一个ColdFusion脚本,它将定期轮询进度日志,直到日志指示FFMpeg已完成其转码操作。在客户端,我可以使用Ajax命中ColdFusion脚本,并在FFMpeg完成工作时向用户显示“完成百分比”。

我通过使用FFMpeg最近版本支持的新“progress”标志来获取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

我想使用CFFILE标记编写一个Coldfusion脚本来读取文件的最后6行(无论文件有多大),并且每次都要执行此操作由浏览器通过Ajax调用。最后,我需要将这些行上的值解析为变量,这样我就可以将一些数据返回给调用者。

我已经研究过FFMpeg的进度条但是它们在PHP中对我来说很难,而且,它们解析了FFMpeg日志文件的旧格式化版本,我想使用上面更新的格式。有人可以帮忙吗?

2 个答案:

答案 0 :(得分: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 for Windows使用MSYS,并且在bin文件夹中有tail.exe。

在这种情况下,上面的第二行改为:

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

如果您需要代码在多个系统上工作,您可以将该部分变为变量(或将相应的目录放在系统PATH上,以便可以从任何地方调用它)。

答案 1 :(得分:0)

这将读取您的文件并创建一个包含最后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行。对于较小的文件(&lt; 200k行),此选项的速度约为2倍,但随着文件大小的增加,两个选项几乎相同,然后第一个选项在大约1M行变得更快

<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>

enter image description here