| 678 | if (confidence != nullptr && !confidence->is_null()) { |
| 679 | word.confidence = confidence->as_f32(); |
| 680 | } |
| 681 | words.push_back(std::move(word)); |
| 682 | } |
| 683 | return words; |
| 684 | } |
| 685 | |
| 686 | void run_format_subtitles_step( |
| 687 | const engine::io::json::Value & step, |
| 688 | WorkflowContext & context) { |
| 689 | const std::string id = workflow_string(step, "id"); |
| 690 | const std::string format = workflow_string(step, "format"); |
| 691 | if (format != "srt") { |
| 692 | throw std::runtime_error("format_subtitles currently supports only format=srt: " + id); |
| 693 | } |
| 694 | const auto words_path = resolve_workflow_path(workflow_string(step, "words"), context); |
| 695 | const auto output = resolve_workflow_path(workflow_string(step, "output"), context); |
| 696 | const auto sample_rate_value = workflow_optional_number(step, "sample_rate"); |
| 697 | if (!sample_rate_value.has_value()) { |
| 698 | throw std::runtime_error("format_subtitles requires sample_rate: " + id); |
| 699 | } |
| 700 | const int sample_rate = static_cast<int>(*sample_rate_value); |
| 701 | engine::text::SubtitleFormatOptions format_options; |
| 702 | format_options.sample_rate = sample_rate; |
| 703 | format_options.max_chars_per_line = |
| 704 | static_cast<int>(workflow_optional_number(step, "max_chars_per_line").value_or(42.0)); |
| 705 | format_options.max_lines = |
| 706 | static_cast<int>(workflow_optional_number(step, "max_lines").value_or(2.0)); |
| 707 | format_options.max_block_seconds = workflow_optional_number(step, "max_block_seconds").value_or(6.0); |
| 708 | format_options.max_gap_seconds = workflow_optional_number(step, "max_gap_seconds").value_or(1.0); |
| 709 | |
| 710 | const auto words = read_word_timestamps_json(words_path); |
| 711 | const auto srt = engine::text::format_srt(words, format_options); |
| 712 | if (!output.parent_path().empty()) { |
| 713 | std::filesystem::create_directories(output.parent_path()); |
| 714 | } |
| 715 | std::ofstream out(output); |
| 716 | out << srt; |
| 717 | context.values[id + ".srt_path"] = output.string(); |
no test coverage detected