3

ColdFusion の CFFILE タグを使用してテキスト ファイルの内容を読み取る方法を知りたいです。私の場合、そのテキスト ファイルは、メディア ファイルのトランスコード中に FFMpeg によって生成される進行状況ログです。FFMpeg がトランスコーディング操作を終了したことをログが示すまで、進行状況ログを定期的にポーリングする ColdFusion スクリプトを作成したいと考えています。クライアント側では、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

CFFILE タグを使用してファイルの最後の 6 行のみを読み取り(ファイルのサイズに関係なく)、Coldfusion スクリプトを作成し、Ajax 経由でブラウザーによってスクリプトが呼び出されるたびにこれを実行したいと考えています。最後に、これらの行の値を変数に解析して、呼び出し元にデータを返せるようにする必要があります。

私は FFMpeg のプログレス バーを調査しましたが、それらは PHP にあり、私には難しいです。さらに、FFMpeg のログ ファイルの古い形式のバージョンを解析し、上記の新しい形式を使用したいと考えています。誰でも助けてもらえますか?

4

2 に答える 2

2

最後の 6 行の末尾を取得する方が高速になります。これは、ファイル全体を読み取ってからループするのではなく、逆方向に動作し、要求したものだけをロードするためです。ファイルサイズに関係なく、メモリの使用量も明らかに少なくなります。

<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 があります。

その場合、上記の 2 行目は次のように変更されます。

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

コードを複数のシステムで動作させる必要がある場合は、その部分を変数にすることができます (または、適切なディレクトリをシステム PATH に配置して、どこからでも呼び出せるようにします)。

于 2013-05-04T15:20:21.240 に答える
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 行をそのように引き出すこともできます。このオプションは、小さいファイル (<200k 行) では約 2 倍高速ですが、ファイル サイズが大きくなると、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>

ここに画像の説明を入力

于 2013-05-04T01:14:45.170 に答える