2016-07-01 4 views
1

私はWindowsのスクリプトに全く慣れていませんが、このようなスクリプトを使用することを余儀なくされています。誰かが私に次の問題を手伝ってほしいです。私はffmpegコマンドの出力を処理して、後で使用するWebカメラへのアクセスに関する情報を保存したいと思っています。ffmpeg出力はバッチスクリプトで解析されます

ffmpeg -stats -hide_banner -list_devices true -f dshow -i dummy 

を、出力は次のようである: より正確コマンド以下、典型的に

[dshow @ 02cec400] DirectShow video devices (some may be both video and audio devices) 
[dshow @ 02cec400] "Microsoft LifeCam Studio" 
[dshow @ 02cec400]  Alternative name "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" 
[dshow @ 02cec400] DirectShow audio devices 
[dshow @ 02cec400] "Desktop Microphone (3- Studio -" 
[dshow @ 02cec400]  Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio -" 
[dshow @ 02cec400] "Line In (High Definition Audio " 
[dshow @ 02cec400]  Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Line In (High Definition Audio " 
[dshow @ 02cec400] "Microphone (High Definition Aud" 
[dshow @ 02cec400]  Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Microphone (High Definition Aud" 

、DirectShowのから「代替名」の最初の二つの出現は、簡略化のためにそう、ビデオおよびオーディオに対応するIこれら2つの情報を2つの変数に保存します。この例で は次のとおりです。

@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global 

@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio - 

誰かがもっとこのタスクで私を助けるために経験したことができますか? ありがとうございます!

答えて

1

あなたは(untestet!)、これを試してみてください

 
@echo off&setlocal disabledelayedexpansion 
set "Alt1=" 
set "Alt2=" 
For /f tokens^=1^,2delims^=^" %%a in ('ffmpeg -stats -hide_banner -list_devices true -f dshow -i dummy 2^>^&1 ^| findstr /c:"Alternative name"') do (
    if not defined Alt1 (
     set "Alt1=%%~b" 
    ) else (
     if not defined Alt2 (
     set "Alt2=%%~b" 
    ) 
    ) 
) 
echo Alternative name 1: "%Alt1%" 
echo Alternative name 2: "%Alt2%" 
+0

魅力的な作品!どうもありがとう! バッチスクリプトを登録商標記号で処理する方法の提案があります。マイクロソフトWebカメラにはこの名前のサインがあり、奇妙なシンボルが表示されます。私は、コンソールで使用されるフォントに関連するものだと思います。 – vlad2005

+0

@ vlad2005これは非常に困難な問題です。ローカルの設定によって異なりますので、[こちら](http://stackoverflow.com/a/17177904/2098699)をお読みください。もしそうなら、私の答えに合格とマークしてください。ありがとう。 – Endoro

1

このバッチコードは、変数DeviceVideoへの最初のデバイス文字列と変数DeviceAudioへの第二のデバイス文字列を割り当てます。代わりに、間違いなくコンソールアプリケーションのための一般的ではありませんSTDOUTSTDERRを処理するための

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 
set "DeviceCount=0" 

for /F "tokens=4,5*" %%A in ('ffmpeg.exe -stats -hide_banner -list_devices true -f dshow -i dummy 2^>^&1') do (
    if "%%A %%B" == "Alternative name" (
     set /A DeviceCount+=1 
     if "!DeviceCount!" == "1" (
      set "DeviceVideo=%%~C" 
     ) else (
      set "DeviceAudio=%%~C" 
      goto DevicesOutput 
     ) 
    ) 
) 

:DevicesOutput 
set Device 
endlocal 

ffmpeg出力テキストメッセージ。コマンドの場合は、STDOUTに印刷されたテキストをキャプチャして処理するだけです。 MicrosoftがTechNetの記事Using command redirection operatorsに説明するよう2>&1を使用してSTDOUTを処理するためにSTDERRを処理するためにffmpegにより、すべての出力をリダイレクトする必要がある。そのため

。このリダイレクトはffmpegの実行に及びません FOR の実行時に適用されなければならないので、^オペレーター>&でエスケープする必要があります。プロセスFOR

コマンドセミコロン(デフォルトeol)で始まる空白行もの行をスキップしてffmpegの出力ラインの横。

各行は区切り文字としてスペース/タブを使用して文字列に分割されます(デフォルトはdelims)。​​で指定されているのは、文字列4,5、および5番目のスペース/タブで区切られた文字列の残りの部分のみが対象となり、ループ変数A,B、およびCに割り当てる必要があります。

は、例えばライン

[dshow @ 02cec400]  Alternative name "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" 

は...文字列

  1. [dshow に分割1が指定されていないとして、トークンは無視されます。
  2. @ ...トークン2が指定されていないため無視されます。
  3. 02cec400] ...トークン3が指定されていないため無視されます。
  4. Alternative ...ループ変数Aに割り当てられたトークン4。
  5. name ...ループ変数Bに割り当てられたトークン5。
  6. "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" ...ループ変数Cに割り当てられた*の残りの行(空白とタブ付き)で指定されたトークン6。二重引用符で囲まれた大文字と小文字を区別した文字列比較をループ変数AB場合との間の単一の空間と、チェックさせてループ、内部

ストリング"Alternative name"等しいです。 2つの文字列を比較する前に、二重引用符はIFで削除されません。

等しい文字列では、出力に新しいデバイス名があるため、単純な算術式を使用して環境変数が1つ増えます。すでにそのようなブロックを見つけることに

のWindowsのコマンド・インタープリターは(で定義されたコマンドブロック内に参照される各環境変数の現在の値によって構文%VariableName%を持つすべての環境変数の参照を置き換え... )%DeviceCount%がコマンドブロックで使用される場合、各ループ実行は、FORループの上の行で定義されているように、値0で実行されます。したがって、遅延拡張はデフォルトで有効になっていないため、構文!DeviceCount!を使用して遅延拡張を明示的に有効にすると、遅延拡張が使用されます。

注:コマンドもSETLOCAL押すコマンド拡張機能と遅延展開の現在の状態だけでなく、現在のディレクトリと、スタック上の現在の環境変数テーブルへのポインタとのために全体の環境変数テーブルのコピーを作成します使用(一致)ローカルローカルまたはバッチファイル処理の終了。

ため%%~C代わりにちょうど%%Cの周囲の二重引用符なしデバイス文字列は環境変数DeviceCountの値に応じて可変DeviceVideoまたは可変DeviceAudioのいずれかに割り当てられます。

最初の2つのデバイスストリングのみが対象であるため、2番目のデバイスストリングをDeviceAudioに割り当てた後、ループはすでに終了しています。

サブDeviceで始まるすべての変数は、アルファベット順に出力して、たとえば、その結果、次の処理された行にソート出力されます。コマンドDeviceAudio ENDLOCAL現在の環境変数のテーブルと最後に

[email protected]_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio - 
DeviceCount=2 
[email protected]_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global 

DeviceCountをコマンド拡張(デフォルトで有効)と遅延拡張(デフォルトでは無効)と現在のディレクトリ(まったく変更されていない)がリストアされ、初期環境変数テーブルが作成されます再度アクティブにする。

使用されているコマンドをさらによく理解するには、コマンドプロンプトウィンドウを開き、次のコマンドを実行し、コマンドごとに表示されるすべてのヘルプページをすべて慎重に読み込みます。

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?
関連する問題