Skip to content

Commit 3c13201

Browse files
committed
fixed the exporting issue
1 parent 78bc5cf commit 3c13201

2 files changed

Lines changed: 50 additions & 32 deletions

File tree

include/pythonic/pythonicPrint.hpp

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,28 +1327,54 @@ namespace pythonic
13271327
std::cout << "\n\033[90mUsing CPU encoder (GPU disabled by user)\033[0m\n";
13281328
}
13291329

1330-
// Build encoder-specific options
1331-
std::string encoder_opts;
1332-
if (encoder == "h264_nvenc")
1330+
// Build encoder-specific options (returns pair: encoder_opts, is_hw_encoder)
1331+
auto build_encoder_opts = [](const std::string &enc) -> std::pair<std::string, bool>
13331332
{
1334-
encoder_opts = "-c:v h264_nvenc -preset fast -rc vbr -cq 23";
1335-
}
1336-
else if (encoder == "h264_qsv")
1337-
{
1338-
encoder_opts = "-c:v h264_qsv -preset faster -global_quality 23";
1339-
}
1340-
else if (encoder == "h264_vaapi")
1341-
{
1342-
encoder_opts = "-vaapi_device /dev/dri/renderD128 -c:v h264_vaapi -qp 23";
1343-
}
1344-
else if (encoder == "h264_videotoolbox")
1345-
{
1346-
encoder_opts = "-c:v h264_videotoolbox -q:v 65";
1347-
}
1348-
else
1333+
if (enc == "h264_nvenc")
1334+
return {"-c:v h264_nvenc -preset fast -rc vbr -cq 23", true};
1335+
if (enc == "h264_qsv")
1336+
return {"-c:v h264_qsv -preset faster -global_quality 23", true};
1337+
if (enc == "h264_vaapi")
1338+
return {"-vaapi_device /dev/dri/renderD128 -c:v h264_vaapi -qp 23", true};
1339+
if (enc == "h264_videotoolbox")
1340+
return {"-c:v h264_videotoolbox -q:v 65", true};
1341+
return {"-c:v libx264 -preset faster -crf 23", false};
1342+
};
1343+
1344+
auto [encoder_opts, is_hw_encoder] = build_encoder_opts(encoder);
1345+
1346+
// Video filter to ensure dimensions are divisible by 2 (required for yuv420p)
1347+
// Using single quotes for shell compatibility
1348+
std::string scale_filter = "-vf 'scale=trunc(iw/2)*2:trunc(ih/2)*2'";
1349+
1350+
// Lambda to build and execute FFmpeg command with fallback
1351+
auto run_encode = [&](const std::string &audio_path) -> int
13491352
{
1350-
encoder_opts = "-c:v libx264 -preset faster -crf 23";
1351-
}
1353+
// Use glob pattern for input to handle non-sequential frame numbers
1354+
// (some frames may fail to render, causing gaps in the sequence)
1355+
std::string base_input = "-framerate " + fps_str + " -pattern_type glob -i '" + temp_dir + "/ascii_*.png'";
1356+
std::string audio_input = audio_path.empty() ? "" : " -i '" + audio_path + "'";
1357+
std::string audio_opts = audio_path.empty() ? "" : " -c:a aac -shortest";
1358+
std::string pix_fmt = " -pix_fmt yuv420p";
1359+
1360+
// Try with hardware encoder first
1361+
std::string video_cmd = "ffmpeg -y " + base_input + audio_input + " " +
1362+
scale_filter + " " + encoder_opts + audio_opts + pix_fmt +
1363+
" '" + output_path + "' 2>/dev/null";
1364+
int res = std::system(video_cmd.c_str());
1365+
1366+
// If hardware encoder fails, fallback to CPU encoder
1367+
if (res != 0 && is_hw_encoder)
1368+
{
1369+
std::cout << "\n\033[33mHardware encoder failed, falling back to CPU (libx264)\033[0m\n";
1370+
std::string cpu_opts = "-c:v libx264 -preset faster -crf 23";
1371+
video_cmd = "ffmpeg -y " + base_input + audio_input + " " +
1372+
scale_filter + " " + cpu_opts + audio_opts + pix_fmt +
1373+
" '" + output_path + "' 2>/dev/null";
1374+
res = std::system(video_cmd.c_str());
1375+
}
1376+
return res;
1377+
};
13521378

13531379
// Combine ASCII frames into video
13541380
if (audio == Audio::on)
@@ -1360,26 +1386,18 @@ namespace pythonic
13601386

13611387
if (audio_result == 0)
13621388
{
1363-
// Create video with audio using detected encoder
1364-
std::string video_cmd = "ffmpeg -y -framerate " + fps_str + " -i \"" + temp_dir + "/ascii_%05d.png\" "
1365-
"-i \"" +
1366-
audio_path + "\" " + encoder_opts + " -c:a aac -pix_fmt yuv420p "
1367-
"-shortest \"" +
1368-
output_path + "\" 2>/dev/null";
1369-
result = std::system(video_cmd.c_str());
1389+
result = run_encode(audio_path);
13701390
}
13711391
else
13721392
{
13731393
// No audio in source or extraction failed, create video without audio
1374-
std::string video_cmd = "ffmpeg -y -framerate " + fps_str + " -i \"" + temp_dir + "/ascii_%05d.png\" " + encoder_opts + " -pix_fmt yuv420p \"" + output_path + "\" 2>/dev/null";
1375-
result = std::system(video_cmd.c_str());
1394+
result = run_encode("");
13761395
}
13771396
}
13781397
else
13791398
{
1380-
// Create video without audio using detected encoder
1381-
std::string video_cmd = "ffmpeg -y -framerate " + fps_str + " -i \"" + temp_dir + "/ascii_%05d.png\" " + encoder_opts + " -pix_fmt yuv420p \"" + output_path + "\" 2>/dev/null";
1382-
result = std::system(video_cmd.c_str());
1399+
// Create video without audio
1400+
result = run_encode("");
13831401
}
13841402

13851403
// Cleanup

test_video_export_debug

980 KB
Binary file not shown.

0 commit comments

Comments
 (0)