From bb3ebdd9d6dca5094e3210dba902f98c0ee875e8 Mon Sep 17 00:00:00 2001 From: baxtree Date: Mon, 30 Dec 2019 11:22:35 +0000 Subject: [PATCH] add manual pages and fix configuration for tox --- .gitignore | 14 ++-- .readthedocs.yml | 21 ++++++ LICENCE => LICENSE | 4 +- Makefile | 43 +++++++----- README.md | 14 ++-- 1st_stage.png => figures/1st_stage.png | Bin 2nd_stage.png => figures/2nd_stage.png | Bin requirements-docs.txt | 2 + setup.py | 39 ++++++----- site/Makefile | 26 +++++++ site/source/_static/.gitkeep | 0 site/source/_templates/.gitkeep | 0 site/source/acknowledgement.rst | 13 ++++ site/source/anatomy.rst | 28 ++++++++ site/source/conf.py | 93 +++++++++++++++++++++++++ site/source/index.rst | 35 ++++++++++ site/source/installation.rst | 22 ++++++ site/source/license.rst | 8 +++ site/source/test.rst | 15 ++++ site/source/usage.rst | 24 +++++++ tox.ini | 52 ++++++++++++-- 21 files changed, 399 insertions(+), 54 deletions(-) create mode 100644 .readthedocs.yml rename LICENCE => LICENSE (95%) rename 1st_stage.png => figures/1st_stage.png (100%) rename 2nd_stage.png => figures/2nd_stage.png (100%) create mode 100644 requirements-docs.txt create mode 100644 site/Makefile create mode 100644 site/source/_static/.gitkeep create mode 100644 site/source/_templates/.gitkeep create mode 100644 site/source/acknowledgement.rst create mode 100644 site/source/anatomy.rst create mode 100644 site/source/conf.py create mode 100644 site/source/index.rst create mode 100644 site/source/installation.rst create mode 100644 site/source/license.rst create mode 100644 site/source/test.rst create mode 100644 site/source/usage.rst diff --git a/.gitignore b/.gitignore index b290ea7..07dc7bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,8 @@ *__pycache__* .venv* -BUILD* -src/subaligner.egg-info* +build* dist* *.pyc -.idea .vscode *.DS_Store* .eggs @@ -12,9 +10,13 @@ tests/subaligner/resource/test.mp4.aac tests/subaligner/resource/test.mp4.wav tests/subaligner/training.log tests/subaligner/output.log -training.log -output.log -program.prof +*training.log* +*output.log* +*program.prof* +site/build +site/source/subaligner.rst +site/source/modules.rst +*subaligner.egg-info* # Unit test / coverage reports htmlcov/ diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..7530e16 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,21 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: site/source/conf.py + +# Build documentation with MkDocs +#mkdocs: +# configuration: mkdocs.yml + +# Optionally build your docs in additional formats such as PDF and ePub +formats: all + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.6 diff --git a/LICENCE b/LICENSE similarity index 95% rename from LICENCE rename to LICENSE index eaee294..3540ec4 100644 --- a/LICENCE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2019 Xi Bai +Copyright (c) 2019-present Xi Bai + +The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 0cfb5b1..c7a7df1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build-gzip +.PHONY: install uninstall build-gzip build-rpm test test-all pydoc coverage manual clean clean-gzip clean-doc clean-manual clean-build clean-pyc clean-test clean-rpm define BROWSER_PYSCRIPT import os, webbrowser, sys @@ -14,38 +14,37 @@ BROWSER := python -c "$$BROWSER_PYSCRIPT" ## The versions of pycaption depended by pycaption and aeneas have no overlapping. ## That will fail setup.py so pip install on requirements.txt is needed. install: - if [ ! -e ".venv" ]; then virtualenv -p python3 .venv; fi + if [ ! -e ".venv" ]; then pip3 install virtualenv; virtualenv -p python3 .venv; fi .venv/bin/pip install --upgrade pip setuptools wheel; \ cat requirements.txt | xargs -L 1 .venv/bin/pip install; \ cat requirements-dev.txt | xargs -L 1 .venv/bin/pip install; \ .venv/bin/pip install -e . --ignore-installed - cp ./bin/subaligner_1pass /usr/local/bin/subaligner_1pass - cp ./bin/subaligner_2pass /usr/local/bin/subaligner_2pass + cp ./bin/subaligner_1pass .venv/bin/subaligner_1pass + cp ./bin/subaligner_2pass .venv/bin/subaligner_2pass uninstall: - rm -rf /usr/local/bin/subaligner_1pass - rm -rf /usr/local/bin/subaligner_2pass + rm -f .venv/bin/subaligner_1pass + rm -f .venv/bin/subaligner_2pass build-gzip: mkdir -p dist - tar -czf dist/subligner-cli.tar.gz main bin requirements.txt setup.py tox.ini README.rst HISTORY.rst + tar -czf dist/subligner.tar.gz subaligner bin requirements.txt setup.py README.md LICENCE build-rpm: mkdir -p BUILD RPMS SRPMS SOURCES BUILDROOT - tar -czf SOURCES/subligner-cli.tar.gz main requirements.txt + tar -czf SOURCES/subligner.tar.gz subaligner bin requirements.txt setup.py README.md LICENCE test: ## run tests quickly with the default Python - if [ ! -e ".venv" ]; then virtualenv -p python3 .venv; fi + if [ ! -e ".venv" ]; then pip3 install virtualenv; virtualenv -p python3 .venv; fi .venv/bin/pip install --upgrade pip setuptools wheel; \ cat requirements.txt | xargs -L 1 .venv/bin/pip install; \ cat requirements-dev.txt | xargs -L 1 .venv/bin/pip install PYTHONPATH=. .venv/bin/python -m unittest discover - -.venv/bin/pycodestyle subaligner tests --ignore=E501 + -.venv/bin/pycodestyle subaligner tests --ignore=E203,E501,W503 test-all: ## run tests on every Python version with tox - if [ ! -e ".venv" ]; then virtualenv -p python3 .venv; fi + if [ ! -e ".venv" ]; then pip3 install virtualenv; virtualenv -p python3 .venv; fi .venv/bin/pip install --upgrade pip setuptools wheel; \ - cat requirements.txt | xargs -L 1 .venv/bin/pip install; \ cat requirements-dev.txt | xargs -L 1 .venv/bin/pip install .venv/bin/tox @@ -66,11 +65,10 @@ pydoc: clean-doc ## generate pydoc HTML documentation based on docstrings python -m pydoc -w subaligner.models.training.model; mv subaligner.models.training.model.html docs python -m pydoc -w subaligner.models.training.weights; mv subaligner.models.training.weights.html docs python -m pydoc -w subaligner._version; mv subaligner._version.html docs - $(BROWSER) docs/index.html coverage: ## check code coverage quickly with the default Python - if [ ! -e ".venv" ]; then virtualenv -p python3 .venv; fi + if [ ! -e ".venv" ]; then pip3 install virtualenv; virtualenv -p python3 .venv; fi .venv/bin/pip install --upgrade pip setuptools wheel; \ cat requirements.txt | xargs -L 1 .venv/bin/pip install; \ cat requirements-dev.txt | xargs -L 1 .venv/bin/pip install @@ -79,13 +77,24 @@ coverage: ## check code coverage quickly with the default Python .venv/bin/coverage html $(BROWSER) htmlcov/index.html -clean: clean-build clean-pyc clean-test clean-rpm clean-doc ## remove all build, test, coverage and Python artifacts +manual: clean-manual ## generate manual pages + if [ ! -e ".venv" ]; then pip3 install virtualenv; virtualenv -p python3 .venv; fi + .venv/bin/pip install --upgrade pip setuptools wheel; \ + cat requirements-docs.txt | xargs -L 1 .venv/bin/pip install; \ + SPHINXAPIDOC=../.venv/bin/sphinx-apidoc SPHINXBUILD=../.venv/bin/sphinx-build make -C ./site html + $(BROWSER) ./site/build/html/index.html + +clean: clean-build clean-pyc clean-test clean-rpm clean-doc clean-manual ## remove all build, test, coverage and Python artifacts clean-gzip: rm -rf dist clean-doc: ## remove documents - rm -rf docs/*.html + rm -rf docs/*.html + +clean-manual: ## remove manual pages + rm -rf site/build + rm -f site/source/subaligner.rst site/source/modules.rst clean-build: clean-rpm ## remove build artifacts find . -name '*.egg-info' -exec rm -fr {} + @@ -105,4 +114,4 @@ clean-test: ## remove test and coverage artifacts rm -rf .pytest_cache clean-rpm: - rm -rf BUILD RPMS SRPMS SOURCES BUILDROOT \ No newline at end of file + rm -rf BUILD RPMS SRPMS SOURCES BUILDROOT diff --git a/README.md b/README.md index 8b2fbcb..6cd16c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Build Status](https://travis-ci.com/baxtree/subaligner.svg?branch=master)](https://travis-ci.com/baxtree/subaligner) ![Codecov](https://img.shields.io/codecov/c/github/baxtree/subaligner) -[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/) [![Python 3.5](https://img.shields.io/badge/python-3.5-blue.svg)](https://www.python.org/downloads/release/python-350/) [![Python 3.4](https://img.shields.io/badge/python-3.4-blue.svg)](https://www.python.org/downloads/release/python-340/) - +[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/) [![Python 3.5](https://img.shields.io/badge/python-3.5-blue.svg)](https://www.python.org/downloads/release/python-350/) [![Python 3.4](https://img.shields.io/badge/python-3.4-blue.svg)](https://www.python.org/downloads/release/python-340/) +[![Documentation Status](https://readthedocs.org/projects/subaligner/badge/?version=latest)](https://subaligner.readthedocs.io/en/latest/?badge=latest) +[![GitHub license](https://img.shields.io/github/license/baxtree/subaligner)](https://github.com/baxtree/subaligner/blob/master/LICENSE) ## Dependencies [FFmpeg](https://www.ffmpeg.org/) and [eSpeak](http://espeak.sourceforge.net/index.html) @@ -17,7 +18,7 @@ make install && source .venv/bin/activate ``` # Single-stage alignment (high-level shift with lower latency) -(.venv) $ subaligner_1pass -v video.mp4 -s subtitle.srt + (.venv) $ subaligner_1pass -v video.mp4 -s subtitle.srt ``` ``` @@ -34,13 +35,14 @@ Subtitle: SubRip and TTML Video: MP4, WebM, Ogg, 3GP, FLV and MOV ## Anatomy -Subtitles can be out of sync with their companion audiovisual media files for a variety of causes including latency introduced by Speech-To-Text (STT) on live streams or calibration and rectification involving human intervention during post-production. +Subtitles can be out of sync with their companion audiovisual media files for a variety of causes including latency introduced by Speech-To-Text on live streams or calibration and rectification involving human intervention during post-production. A model has been trained with synchronised video and subtitle pairs and later used for predicating shifting offsets and directions under the guidance of a two-stage aligning approach. First Stage (Global Alignment): -![](1st_stage.png) +![](figures/1st_stage.png) Second Stage (Parallelised Individual Alignment): -![](2nd_stage.png) +![](figures/2nd_stage.png) + diff --git a/1st_stage.png b/figures/1st_stage.png similarity index 100% rename from 1st_stage.png rename to figures/1st_stage.png diff --git a/2nd_stage.png b/figures/2nd_stage.png similarity index 100% rename from 2nd_stage.png rename to figures/2nd_stage.png diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 0000000..bddb8aa --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,2 @@ +sphinx==2.3.1 +sphinx-rtd-theme==0.4.3 diff --git a/setup.py b/setup.py index af6d9fa..a0c449e 100644 --- a/setup.py +++ b/setup.py @@ -3,43 +3,48 @@ import os -from setuptools import setup, find_packages +from setuptools import setup -with open(os.path.join("subaligner", "_version.py")) as f: +with open(os.path.join(os.getcwd(), "subaligner", "_version.py")) as f: exec(f.read()) with open("README.md") as readme_file: readme = readme_file.read() -with open('requirements.txt') as requirements_file: - requirements = requirements_file.read().splitlines() +with open("requirements.txt") as requirements_file: + requirements = requirements_file.read().splitlines()[::-1] -with open('requirements-dev.txt') as requirements_dev_file: - requirements_dev = requirements_dev_file.read().splitlines() +with open("requirements-dev.txt") as requirements_dev_file: + requirements_dev = requirements_dev_file.read().splitlines()[::-1] setup(name="subaligner", version=__version__, author="Xi Bai", author_email="xi.bai.ed@gmail.com", classifiers=[ - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", ], license="MIT", - url="git@bitbucket.org:baxtree/subaligner-cli.git", - description="Automatically align an out-of-sync subtitle to its video with DNN", - long_description=readme + '\n\n', - python_requires='>=3.4', + url="git@github.com:baxtree/subaligner.git", + description="Automatically aligns an out-of-sync subtitle file to its companion video/audio using Deep Neural Network and Forced Alignment.", + long_description=readme + "\n\n", + python_requires=">=3.4", package_dir={"subaligner": "subaligner"}, - packages=find_packages("subaligner"), + packages=[ + "subaligner", + "subaligner.models.training.model", + "subaligner.models.training.weights", + ], package_data={ "subaligner.models.training.model": ["model.hdf5"], "subaligner.models.training.weights": ["weights.hdf5"] }, - setup_requires=["numpy"], install_requires=requirements, test_suite="tests.subaligner", - tests_require=requirements_dev + tests_require=requirements_dev, + setup_requires=["numpy>=1.14.1,<1.18.0"], + scripts=["bin/subaligner_1pass", "bin/subaligner_2pass"], ) \ No newline at end of file diff --git a/site/Makefile b/site/Makefile new file mode 100644 index 0000000..7a6b607 --- /dev/null +++ b/site/Makefile @@ -0,0 +1,26 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SPHINXAPIDOC ?= sphinx-apidoc +SOURCEDIR = source +BUILDDIR = build +INCLUDED = ../subaligner +EXCLUDED = ../subaligner/models + + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + rm -f "$(SOURCEDIR)/subaligner.rst" + rm -f "$(SOURCEDIR)/modules.rst" + $(SPHINXAPIDOC) -o "$(SOURCEDIR)" "$(INCLUDED)" "$(EXCLUDED)" && $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/site/source/_static/.gitkeep b/site/source/_static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/site/source/_templates/.gitkeep b/site/source/_templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/site/source/acknowledgement.rst b/site/source/acknowledgement.rst new file mode 100644 index 0000000..8b83ce1 --- /dev/null +++ b/site/source/acknowledgement.rst @@ -0,0 +1,13 @@ +######################## +Acknowledgement +######################## + + +**Dependencies**:: + + librosa + tensorflow + scikit-learn + pycaption + pysrt + aeneas diff --git a/site/source/anatomy.rst b/site/source/anatomy.rst new file mode 100644 index 0000000..b987bd2 --- /dev/null +++ b/site/source/anatomy.rst @@ -0,0 +1,28 @@ +######################## +Anatomy +######################## + +Under the hood, a model has been trained with synchronised video and subtitle pairs and later used for predicating +shifting offsets and directions under the guidance of a two-stage aligning approach. + +The following figure depicts the primary workflow of the first-stage subtitle alignment. It also includes upfront +network training and later-on subtitle shifting. The data set used for training contains pairs of a video clip and +a subtitle file with decent start and end time codes. Mel-Frequency Cepstral Coefficients are extracted in parallel +and fed into a carefully designed DNN incorporating LSTM layers. For subtitle shifting, an out-of-sync subtitle file +and a target video clip are fed in as input and the output can be either time offsets by which the subtitle should be +shifted or a ready-to-playback subtitle file with calibrated start and end time. Notably, the shifting illustrated here +leads to the completion of the first stage alignment (global shifting). + +.. image:: ../../figures/1st_stage.png + :width: 500 + :align: center + :alt: Illustration on First Stage Alignment + +At the second stage, the target video clip and the globally shifted subtitle file will be broken down into evenly +timed chunks respectively, each pair of which will be fed into the DNN and aligned in parallel (regional shifting) as +shown in the following figure. And the concatenated subtitle chunks result in the final output. + +.. image:: ../../figures/2nd_stage.png + :width: 500 + :align: center + :alt: Illustration on Second Stage Alignment \ No newline at end of file diff --git a/site/source/conf.py b/site/source/conf.py new file mode 100644 index 0000000..f3513c2 --- /dev/null +++ b/site/source/conf.py @@ -0,0 +1,93 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + + +sys.path.insert(0, os.path.abspath("../..")) +with open(os.path.join(os.getcwd(), "..", "..", "subaligner", "_version.py")) as f: + exec(f.read()) + +# -- Project information ----------------------------------------------------- + +project = "subaligner" +copyright = "2019, Xi Bai" +author = "Xi Bai" +master_doc = "index" + +# The full version, including alpha/beta/rc tags +release = __version__ + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named "sphinx.ext.*") or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.ifconfig", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +autodoc_mock_imports = [ + "absl", + "absl-py", + "aeneas", + "h5py", + "librosa", + "matplotlib", + "numpy", + "pycaption", + "pysrt", + "sklearn", + "tensorflow", + "matplotlib", +] + +def setup(app): + if os.getenv("READTHEDOCS", False): + def run_apidoc(_): + from sphinx.ext.apidoc import main as apidoc_main + cur_dir = os.path.abspath(os.path.dirname(__file__)) + included_module = "../../subaligner" + excluded_module = "../../subaligner/models" + apidoc_main(["-e", "-o", cur_dir, included_module, excluded_module, "--force"]) + app.connect("builder-inited", run_apidoc) + else: + pass diff --git a/site/source/index.rst b/site/source/index.rst new file mode 100644 index 0000000..ad51cfd --- /dev/null +++ b/site/source/index.rst @@ -0,0 +1,35 @@ +.. subaligner documentation master file, created by + sphinx-quickstart on Wed Dec 25 23:33:25 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Subaligner's documentation! +====================================== + +Given an out-of-sync subtitle file along with a piece of audiovisual content carrying speeches described by it, +Subaligner provides a one-stop solution on automatic subtitle alignment based on Deep Neural Network and Forced +Alignment. In essence, aligning subtitles is a two-stage process with a Bidirectional Long Short-Term Memory network trained +upfront and Subaligner helps subtitlers not only in preprocessing raw subtitle materials (outcome from stenographers or +STT workflow, etc.) but also in gaining quality control over their work within subtitle post-production. This solution +also tolerates errors occurred in live subtitles which sometimes do not completely or correctly represent what people +actually spoke in the companion audiovisual content. + +The source code can be found on GitHub: `subaligner `_. + +.. toctree:: + :maxdepth: 2 + + installation + usage + anatomy + test + acknowledgement + license + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/site/source/installation.rst b/site/source/installation.rst new file mode 100644 index 0000000..3daa2da --- /dev/null +++ b/site/source/installation.rst @@ -0,0 +1,22 @@ +######################## +Installation +######################## + +Subaligner is not available on PyPi's repo yet. To quickly get it installed and running, you can clone the +`GitHub repo `_ and follow the steps down below +to create a virtual environment and set up all the dependencies: + +**Use HomeBrew* to install necessary packages**:: + + $ brew install ffmpeg espeak + +**Install dependencies and activate the virtual environment**:: + + $ make install && source .venv/bin/activate + +**subaligner_1pass and subaligner_2pass should be on your PATH now**:: + + (.venv) $ subaligner_1pass --help + (.venv) $ subaligner_2pass --help + +*How to install `HomeBrew `_ \ No newline at end of file diff --git a/site/source/license.rst b/site/source/license.rst new file mode 100644 index 0000000..1ec041f --- /dev/null +++ b/site/source/license.rst @@ -0,0 +1,8 @@ +######################## +License +######################## + +.. highlight:: none + +.. include:: ../../LICENSE + :literal: diff --git a/site/source/test.rst b/site/source/test.rst new file mode 100644 index 0000000..1614c01 --- /dev/null +++ b/site/source/test.rst @@ -0,0 +1,15 @@ +######################## +Test +######################## + +**Run unit tests**:: + + $ make test + +**Run test coverage**:: + + $ make coverage + +**Run tests with target Python versions**:: + + $ make test-all diff --git a/site/source/usage.rst b/site/source/usage.rst new file mode 100644 index 0000000..91c7ec6 --- /dev/null +++ b/site/source/usage.rst @@ -0,0 +1,24 @@ +######################## +Usage +######################## + +Subaligner provides two ways of aligning subtitles: single-stage alignment and dual-stage alignment. The former way has +lower latency and shifts all subtitle segments globally. The latter way has higher latency and shifts the +segments individually with an option of stretching each segment. + +Make sure you have got the virtual environment activated upfront. + +**Single-stage alignment**:: + + (.venv) $ subaligner_1pass -v video.mp4 -s subtitle.srt + +**Dual-stage alignment**:: + + (.venv) $ subaligner_2pass -v video.mp4 -s subtitle.srt + +Currently the stretching is experimental and only works for speech and subtitles in English. + +**Use flag "-so" to switch off stretching when aligning subtitles not in English**:: + + (.venv) $ subaligner_2pass -v video.mp4 -s subtitle.srt -so + diff --git a/tox.ini b/tox.ini index 5bd17f0..847d2b5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,11 @@ [tox] -envlist = py34, py35, py36 +envlist = + py34, + py35, + py36, + lint, + coverage +skipsdist=True [travis] python = @@ -7,9 +13,41 @@ python = 3.5: py35 3.4: py34 -[testenv] -basepython = python -deps = - -rrequirements.txt - -rrequirements-dev.txt -commands = python -m unittest discover \ No newline at end of file +[testenv:py34] +basepython = python3 +whitelist_externals = /bin/bash +commands = + bash -c \'cat requirements.txt | xargs -L 1 pip3 install\' + bash -c \'cat requirements-dev.txt | xargs -L 1 pip3 install' + python3 -m unittest discover + +[testenv:py35] +basepython = python3 +whitelist_externals = /bin/bash +commands = + bash -c \'cat requirements.txt | xargs -L 1 pip3 install\' + bash -c \'cat requirements-dev.txt | xargs -L 1 pip3 install' + python3 -m unittest discover + +[testenv:py36] +basepython = python3 +whitelist_externals = /bin/bash +commands = + bash -c \'cat requirements.txt | xargs -L 1 pip3 install\' + bash -c \'cat requirements-dev.txt | xargs -L 1 pip3 install' + python3 -m unittest discover + +[testenv:lint] +whitelist_externals = /bin/bash +commands = + bash -c \'cat requirements-dev.txt | xargs -L 1 pip3 install' + pycodestyle subaligner tests --ignore=E203,E501,W503 + +[testenv:coverage] +basepython = python3 +whitelist_externals = /bin/bash +commands = + bash -c \'cat requirements.txt | xargs -L 1 pip3 install\' + bash -c \'cat requirements-dev.txt | xargs -L 1 pip3 install' + coverage run --source subaligner -m unittest discover + coverage report --fail-under=85 \ No newline at end of file