[M1 Mac, Big Sur 11.6.8, clang 13.0.0, FLTK 1.3.8, NO IDE]
開発中のビデオツールアプリで動画の縦横サイズを取得し、Fl_Inputに表示させました。
ffproveコマンドの出力をFILE構造体として取得、fgets関数でcharとしてデータを取り出し、xを区切り文字にしてリスト化しました。0番目の要素がwidth、1番目の要素がheightになります。
最初、変数resultのメモリ領域を確保せずにchar *resultとしていたところ、ビルドは成功しましたが、アプリとして動作させるとセグメンテーション違反が発生しました。正しくは、char result[受け取るデータの最大バイト数]になります。データを格納する時はポインタ変数を設定するのではなく、あらかじめその領域を確保しておく必要があります。初心者にありがちなミスでした。
void inspect(){
char count[100];
// 対象ファイルパス取得
const char* path = input_line->value();
cout << "path "<< path << endl;
string path_str = string(path);
bufferstr += "path_str: " + path_str + "\n";
// path内半角スペースをアンダースコアへ置き換え
string path2 = underScoreReplace(string(path_str));
bufferstr += "path2: " + path2 + "\n";
// 元ファイルをリネーム
rename(path, path2.c_str());
// ファイル縦横サイズ出力コマンド作成
string cmd = "/opt/homebrew/Cellar/ffmpeg/5.1/bin/ffprobe -v error -select_streams v -show_entries stream=width,height -of csv=p=0:s=x " + path2;
cout << "cmd: "<< cmd << endl;
// cmdをtextBufferに追記
string cmdstr = "cmd: " + cmd + "\n";
textBuffer->append(cmdstr.c_str());
// 文字数と行数をカウントしtextBufferに追記
int length_buf = textBuffer -> length();
int num_lines = textBuffer -> count_lines(0, length_buf);
printf("length_buf %d num_lines %d\n",length_buf,num_lines);
sprintf(count, "length_buf %d num_lines %d\n",length_buf,num_lines);
textBuffer->append(count);
// textDisplayを最終行表示する
textDisplay->buffer(textBuffer);
textDisplay->scroll(num_lines + 1, 0);
// cmd実行
showInspectResult(cmd);
cout << "inspect完了!" << endl;
}
void showInspectResult(string cmd){
char result[10];
FILE* fp = popen(cmd.c_str(), "r");
fgets(result, 10, fp);
pclose(fp);
string result_str = string(result);
cout << "result_str " << result_str << endl;
vector<string> data = spt.splits(result_str,"x"); // sptは自製クラス
cout << "data[0] " << data[0] << endl;
cout << "data[1] " << data[1] << endl;
width = stoi(data[0]);
height = stoi(data[1]);
cout << "width " << width << endl;
cout << "height " << height << endl;
width_input0 -> value((to_string(width)).c_str());
height_input0 -> value((to_string(height)).c_str());
}