コード例 #1
0
 def test_get_log_loss(self):
     undertest_obj = Undertest(n_mfcc=20)
     subs, audio_file_path, voice_probabilities, frame_rate = undertest_obj.predict_single_pass(
         self.__video_file_path, self.__srt_file_path, self.__weights_dir)
     log_loss = undertest_obj.get_log_loss(voice_probabilities, subs)
     self.assertGreater(log_loss, 0)
     self.assertEqual(24.0, frame_rate)
コード例 #2
0
ファイル: profiler.py プロジェクト: spritenee/subaligner
def kernprof_target():
    examples_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(examples_dir, "tmp")
    os.makedirs(output_dir, exist_ok=True)
    video_file_path = os.path.join(examples_dir, "..", "video.mp4")
    srt_file_path = os.path.join(examples_dir, "..", "subtitle.srt")

    predictor = Predictor()
    predictor.predict_dual_pass(video_file_path, srt_file_path)
コード例 #3
0
    def test_predict_dual_pass_on_audio(self):
        undertest_obj = Undertest(n_mfcc=20)
        new_subs, subs, voice_probabilities, frame_rate = undertest_obj.predict_dual_pass(
            self.__audio_file_path, self.__srt_file_path, self.__weights_dir)

        self.assertGreater(len(new_subs), 0)
        self.assertEqual(len(new_subs), len(subs))
        self.assertGreater(len(voice_probabilities), 0)
        self.assertIsNone(frame_rate)
コード例 #4
0
 def test_throw_exception_on_segment_alignment_failure_when_flag_on(self, mock_time_to_sec):
     try:
         undertest_obj = Undertest(n_mfcc=20)
         undertest_obj.predict_dual_pass(self.__video_file_path, self.__srt_file_path, self.__weights_dir, exit_segfail=True)
     except Exception as e:
         self.assertTrue(mock_time_to_sec.called)
         self.assertTrue(isinstance(e, TerminalException))
         self.assertTrue("At least one of the segments failed on alignment. Exiting..." in str(e))
     else:
         self.fail("Should have thrown exception")
コード例 #5
0
 def test_not_throw_exception_on_segment_alignment_failure(self, mock_time_to_sec):
     undertest_obj = Undertest(n_mfcc=20)
     new_subs, subs, voice_probabilities, frame_rate = undertest_obj.predict_dual_pass(
         self.__video_file_path, self.__srt_file_path, self.__weights_dir
     )
     self.assertGreater(len(new_subs), 0)
     self.assertEqual(len(new_subs), len(subs))
     self.assertGreater(len(voice_probabilities), 0)
     self.assertTrue(mock_time_to_sec.called)
     self.assertEqual(24.0, frame_rate)
コード例 #6
0
 def test_get_log_loss_on_speech_shorter_than_subtitle(self):
     undertest_obj = Undertest(n_mfcc=20)
     shorter_audio_file_path, _ = MediaHelper.extract_audio_from_start_to_end(self.__audio_file_path, "00:00:00,000", "00:00:32,797")
     self.__audio_file_paths.append(shorter_audio_file_path)
     subs, audio_file_path, voice_probabilities, frame_rate = undertest_obj.predict_single_pass(
         shorter_audio_file_path, self.__srt_file_path, self.__weights_dir
     )
     log_loss = undertest_obj.get_log_loss(voice_probabilities, subs)
     self.assertGreater(log_loss, 0)
     self.assertIsNone(frame_rate)
コード例 #7
0
 def test_throw_terminal_exception_on_timeout(self):
     backup = Undertest._Predictor__SEGMENT_PREDICTION_TIMEOUT
     Undertest._Predictor__SEGMENT_PREDICTION_TIMEOUT = 0.05
     try:
         undertest_obj = Undertest(n_mfcc=20)
         undertest_obj.predict_dual_pass(self.__video_file_path, self.__srt_file_path, self.__weights_dir)
     except Exception as e:
         self.assertTrue(isinstance(e, TerminalException))
     else:
         self.fail("Should have thrown exception")
     finally:
         Undertest._Predictor__SEGMENT_PREDICTION_TIMEOUT = backup
コード例 #8
0
 def test_throw_exception_on_predict_interrupted(self, mock_result):
     try:
         undertest_obj = Undertest(n_mfcc=20)
         undertest_obj.predict_dual_pass(self.__video_file_path,
                                         self.__srt_file_path,
                                         self.__weights_dir)
     except Exception as e:
         self.assertTrue(mock_result.called)
         self.assertTrue(isinstance(e, TerminalException))
         self.assertTrue("interrupted" in str(e))
     else:
         self.fail("Should have thrown exception")
コード例 #9
0
    def test_predict_dual_pass_without_stretching_logs(self):
        quiet = Logger.QUIET
        Logger.QUIET = True
        undertest_obj = Undertest(n_mfcc=20)
        new_subs, subs, voice_probabilities, frame_rate = undertest_obj.predict_dual_pass(
            self.__audio_file_path, self.__srt_file_path, self.__weights_dir
        )

        self.assertGreater(len(new_subs), 0)
        self.assertEqual(len(new_subs), len(subs))
        self.assertGreater(len(voice_probabilities), 0)
        self.assertIsNone(frame_rate)
        Logger.QUIET = quiet
コード例 #10
0
ファイル: profiler.py プロジェクト: spritenee/subaligner
def generate_profiles(file_dir="."):
    examples_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(examples_dir, "tmp")
    os.makedirs(output_dir, exist_ok=True)
    video_file_path = os.path.join(examples_dir, "..",
                                   "tests/subaligner/resource/test.mp4")
    srt_file_path = os.path.join(examples_dir, "..",
                                 "tests/subaligner/resource/test.srt")

    predictor = Predictor()
    cProfile.runctx(
        "predictor.predict_dual_pass(video_file_path, srt_file_path)", None,
        locals(), os.path.join(file_dir, "predictor.prof"))

    hyperparameters = Hyperparameters()
    hyperparameters.epochs = 10

    trainer = Trainer(FeatureEmbedder())
    cProfile.runctx(
        ("trainer.train([video_file_path, video_file_path, video_file_path],"
         "[srt_file_path, srt_file_path, srt_file_path],"
         "output_dir,"
         "output_dir,"
         "output_dir,"
         "output_dir,"
         "output_dir,"
         "hyperparameters)"), None, locals(),
        os.path.join(file_dir, "trainer.prof"))
コード例 #11
0
    def test_predict_dual_pass_with_stretching(self):
        undertest_obj = Undertest(n_mfcc=20)

        new_subs, subs, voice_probabilities, frame_rate = undertest_obj.predict_dual_pass(
            self.__video_file_path, self.__srt_file_path, self.__weights_dir, stretch=True
        )
        stretched = False
        for index, sub in enumerate(new_subs):
            if (sub.duration != subs[index].duration):
                stretched = True
                break

        self.assertGreater(len(new_subs), 0)
        self.assertEqual(len(new_subs), len(subs))
        self.assertTrue(stretched)
        self.assertGreater(len(voice_probabilities), 0)
        self.assertEqual(24.0, frame_rate)
コード例 #12
0
def main():
    if sys.version_info.major != 3:
        print("Cannot find Python 3")
        sys.exit(20)
    try:
        import subaligner
    except ModuleNotFoundError:
        print("Subaligner is not installed")
        sys.exit(20)

    parser = argparse.ArgumentParser(
        description="Subaligner command line interface")
    required_args = parser.add_argument_group("required arguments")
    required_args.add_argument(
        "-m",
        "--mode",
        type=str,
        default="",
        choices=["single", "dual"],
        help="Alignment mode: either single or dual",
        required=True,
    )
    required_args.add_argument(
        "-v",
        "--video_path",
        type=str,
        default="",
        help="Path to the video file",
        required=True,
    )
    required_args.add_argument(
        "-s",
        "--subtitle_path",
        type=str,
        default="",
        help="Path to the subtitle file",
        required=True,
    )
    parser.add_argument(
        "-l",
        "--max_logloss",
        type=float,
        default=float("inf"),
        help="Max global log loss for alignment",
    )
    parser.add_argument(
        "-so",
        "--stretch_off",
        action="store_true",
        help="Switch off stretch on non-English speech and subtitles)",
    )
    parser.add_argument(
        "-fos",
        "--exit_segfail",
        action="store_true",
        help="Exit on any segment alignment failures",
    )
    parser.add_argument(
        "-tod",
        "--training_output_directory",
        type=str,
        default=os.path.abspath(os.path.dirname(subaligner.__file__)),
        help="Path to the output directory containing training results",
    )
    parser.add_argument(
        "-o",
        "--output",
        type=str,
        default="",
        help="Path to the output subtitle file",
    )
    parser.add_argument("-d",
                        "--debug",
                        action="store_true",
                        help="Print out debugging information")
    parser.add_argument("-q",
                        "--quiet",
                        action="store_true",
                        help="Switch off logging information")
    FLAGS, unparsed = parser.parse_known_args()

    if FLAGS.mode == "":
        print("--mode was not passed in")
        sys.exit(21)
    if FLAGS.video_path == "":
        print("--video_path was not passed in")
        sys.exit(21)
    if FLAGS.subtitle_path == "":
        print("--subtitle_path was not passed in")
        sys.exit(21)

    exit_segfail = FLAGS.exit_segfail
    stretch = not FLAGS.stretch_off

    from subaligner.logger import Logger
    Logger.VERBOSE = FLAGS.debug
    Logger.QUIET = FLAGS.quiet
    from subaligner.predictor import Predictor
    from subaligner.subtitle import Subtitle
    from subaligner.exception import UnsupportedFormatException
    from subaligner.exception import TerminalException

    try:
        predictor = Predictor()
        if FLAGS.mode == "single":
            aligned_subs, audio_file_path, voice_probabilities, frame_rate = predictor.predict_single_pass(
                video_file_path=FLAGS.video_path,
                subtitle_file_path=FLAGS.subtitle_path,
                weights_dir=os.path.join(FLAGS.training_output_directory,
                                         "models/training/weights"))
        else:
            aligned_subs, subs, voice_probabilities, frame_rate = predictor.predict_dual_pass(
                video_file_path=FLAGS.video_path,
                subtitle_file_path=FLAGS.subtitle_path,
                weights_dir=os.path.join(FLAGS.training_output_directory,
                                         "models/training/weights"),
                stretch=stretch,
                exit_segfail=exit_segfail,
            )
        aligned_subtitle_path = "_aligned.".join(
            FLAGS.subtitle_path.rsplit(
                ".", 1)) if FLAGS.output == "" else FLAGS.output
        Subtitle.export_subtitle(FLAGS.subtitle_path, aligned_subs,
                                 aligned_subtitle_path, frame_rate)
        print("Aligned subtitle saved to: {}".format(aligned_subtitle_path))

        log_loss = predictor.get_log_loss(voice_probabilities, aligned_subs)
        if log_loss is None or log_loss > FLAGS.max_logloss:
            print("Alignment failed with a too high loss value: {}".format(
                log_loss))
            exit(22)
    except UnsupportedFormatException as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        sys.exit(23)
    except TerminalException as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        sys.exit(24)
    except Exception as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        sys.exit(1)
    else:
        exit(0)
コード例 #13
0
ファイル: align.py プロジェクト: spritenee/subaligner
import os
from subaligner.predictor import Predictor
from subaligner.subtitle import Subtitle

if __name__ == "__main__":
    examples_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(examples_dir, "tmp")
    os.makedirs(output_dir, exist_ok=True)
    video_file_path = os.path.join(examples_dir, "..",
                                   "tests/subaligner/resource/test.mp4")
    srt_file_path = os.path.join(examples_dir, "..",
                                 "tests/subaligner/resource/test.srt")

    predictor = Predictor()
    subs, audio_file_path, voice_probabilities, frame_rate = predictor.predict_single_pass(
        video_file_path, srt_file_path)
    aligned_subtitle_path = os.path.join(output_dir, "test_aligned_1.srt")
    Subtitle.export_subtitle(srt_file_path, subs, aligned_subtitle_path)
    print("Aligned subtitle saved to: {}".format(aligned_subtitle_path))

    log_loss = predictor.get_log_loss(voice_probabilities, subs)
    print("Alignment finished with overall loss: {}".format(log_loss))

    subs_list, subs, voice_probabilities, frame_rate = predictor.predict_dual_pass(
        video_file_path, srt_file_path, stretch=False)
    aligned_subtitle_path = os.path.join(output_dir, "test_aligned_2.srt")
    Subtitle.export_subtitle(srt_file_path, subs_list, aligned_subtitle_path)
    print("Aligned subtitle saved to: {}".format(aligned_subtitle_path))

    log_loss = predictor.get_log_loss(voice_probabilities, subs)
    print("Alignment finished with overall loss: {}".format(log_loss))
コード例 #14
0
def main():
    if sys.version_info.major != 3:
        print("Cannot find Python 3")
        sys.exit(20)
    try:
        import subaligner
    except ModuleNotFoundError:
        print("Subaligner is not installed")
        sys.exit(20)

    from subaligner._version import __version__
    parser = argparse.ArgumentParser(
        description="Run single-stage alignment (v%s)" % __version__,
        formatter_class=argparse.RawTextHelpFormatter)
    required_args = parser.add_argument_group("required arguments")
    required_args.add_argument(
        "-v",
        "--video_path",
        type=str,
        default="",
        help="File path or URL to the video file",
        required=True,
    )
    from subaligner.subtitle import Subtitle
    required_args.add_argument(
        "-s",
        "--subtitle_path",
        type=str,
        default="",
        help=
        "File path or URL to the subtitle file (Extensions of supported subtitles: {}) or selector for the embedded subtitle (e.g., embedded:page_num=888 or embedded:stream_index=0)"
        .format(", ".join(Subtitle.subtitle_extensions())),
        required=True,
    )
    parser.add_argument(
        "-l",
        "--max_logloss",
        type=float,
        default=float("inf"),
        help="Max global log loss for alignment",
    )
    parser.add_argument(
        "-tod",
        "--training_output_directory",
        type=str,
        default=os.path.abspath(os.path.dirname(subaligner.__file__)),
        help="Path to the output directory containing training results",
    )
    parser.add_argument(
        "-o",
        "--output",
        type=str,
        default="",
        help="Path to the output subtitle file",
    )
    parser.add_argument("-d",
                        "--debug",
                        action="store_true",
                        help="Print out debugging information")
    parser.add_argument("-q",
                        "--quiet",
                        action="store_true",
                        help="Switch off logging information")
    parser.add_argument("-ver",
                        "--version",
                        action="version",
                        version=__version__)
    FLAGS, unparsed = parser.parse_known_args()

    if FLAGS.video_path == "":
        print("--video_path was not passed in")
        sys.exit(21)
    if FLAGS.subtitle_path == "":
        print("--subtitle_path was not passed in")
        sys.exit(21)
    if FLAGS.subtitle_path.lower().startswith("http") and FLAGS.output == "":
        print(
            "--output was not passed in for alignment on a remote subtitle file"
        )
        sys.exit(21)
    if FLAGS.subtitle_path.lower().startswith(
            "teletext:") and FLAGS.output == "":
        print("--output was not passed in for alignment on embedded subtitles")
        sys.exit(21)

    local_video_path = FLAGS.video_path
    local_subtitle_path = FLAGS.subtitle_path

    from subaligner.logger import Logger
    Logger.VERBOSE = FLAGS.debug
    Logger.QUIET = FLAGS.quiet
    from subaligner.predictor import Predictor
    from subaligner.exception import UnsupportedFormatException
    from subaligner.exception import TerminalException
    from subaligner.utils import Utils

    try:
        if FLAGS.video_path.lower().startswith("http"):
            _, local_video_path = tempfile.mkstemp()
            _, video_file_extension = os.path.splitext(
                FLAGS.video_path.lower())
            local_video_path = "{}{}".format(local_video_path,
                                             video_file_extension)
            Utils.download_file(FLAGS.video_path, local_video_path)

        if FLAGS.subtitle_path.lower().startswith("http"):
            _, local_subtitle_path = tempfile.mkstemp()
            _, subtitle_file_extension = os.path.splitext(
                FLAGS.subtitle_path.lower())
            local_subtitle_path = "{}{}".format(local_subtitle_path,
                                                subtitle_file_extension)
            Utils.download_file(FLAGS.subtitle_path, local_subtitle_path)

        if FLAGS.subtitle_path.lower().startswith("embedded:"):
            _, local_subtitle_path = tempfile.mkstemp()
            _, subtitle_file_extension = os.path.splitext(FLAGS.output)
            local_subtitle_path = "{}{}".format(local_subtitle_path,
                                                subtitle_file_extension)
            params = FLAGS.subtitle_path.lower().split(":")[1].split(",")
            if params and "=" in params[0]:
                params = {
                    param.split("=")[0]: param.split("=")[1]
                    for param in params
                }
                if "page_num" in params:
                    Utils.extract_teletext_as_subtitle(local_video_path,
                                                       int(params["page_num"]),
                                                       local_subtitle_path)
                elif "stream_index" in params:
                    Utils.extract_matroska_subtitle(
                        local_video_path, int(params["stream_index"]),
                        local_subtitle_path)
            else:
                print("Embedded subtitle selector cannot be empty")
                sys.exit(21)

        predictor = Predictor()
        subs, audio_file_path, voice_probabilities, frame_rate = predictor.predict_single_pass(
            video_file_path=local_video_path,
            subtitle_file_path=local_subtitle_path,
            weights_dir=os.path.join(FLAGS.training_output_directory,
                                     "models/training/weights"))

        aligned_subtitle_path = "_aligned.".join(
            FLAGS.subtitle_path.rsplit(".", 1)).replace(
                ".stl", ".srt") if FLAGS.output == "" else FLAGS.output
        Subtitle.export_subtitle(local_subtitle_path, subs,
                                 aligned_subtitle_path, frame_rate)

        log_loss = predictor.get_log_loss(voice_probabilities, subs)
        if log_loss is None or log_loss > FLAGS.max_logloss:
            print("Alignment failed with a too high loss value: {}".format(
                log_loss))
            _remove_tmp_files(FLAGS, local_video_path, local_subtitle_path)
            sys.exit(22)

        print("Aligned subtitle saved to: {}".format(aligned_subtitle_path))
    except UnsupportedFormatException as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        _remove_tmp_files(FLAGS, local_video_path, local_subtitle_path)
        sys.exit(23)
    except TerminalException as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        _remove_tmp_files(FLAGS, local_video_path, local_subtitle_path)
        sys.exit(24)
    except Exception as e:
        print("{}\n{}".format(
            str(e), "".join(traceback.format_stack()) if FLAGS.debug else ""))
        _remove_tmp_files(FLAGS, local_video_path, local_subtitle_path)
        sys.exit(1)
    else:
        _remove_tmp_files(FLAGS, local_video_path, local_subtitle_path)
        sys.exit(0)