├── src └── ffmpeg_bitrate_stats │ ├── py.typed │ ├── __init__.py │ ├── log.py │ ├── __main__.py │ └── bitrate_stats.py ├── tests ├── test.mp4 ├── test_keyframes.mp4 ├── without_timestamps.mp4 └── test_ffmpeg_bitrate_stats.py ├── .github ├── ISSUE_TEMPLATE │ ├── question.md │ ├── feature_request.md │ └── bug_report.md ├── CONTRIBUTING.md ├── FUNDING.yml └── workflows │ └── python-package.yml ├── docs ├── index.html └── search.js ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── .all-contributorsrc ├── LICENSE.md ├── pyproject.toml ├── .gitignore └── README.md /src/ffmpeg_bitrate_stats/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slhck/ffmpeg-bitrate-stats/HEAD/tests/test.mp4 -------------------------------------------------------------------------------- /tests/test_keyframes.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slhck/ffmpeg-bitrate-stats/HEAD/tests/test_keyframes.mp4 -------------------------------------------------------------------------------- /tests/without_timestamps.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slhck/ffmpeg-bitrate-stats/HEAD/tests/without_timestamps.mp4 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question/Support 3 | about: I am stuck with something and need help (not a bug or error) 4 | 5 | --- 6 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/ffmpeg_bitrate_stats/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib.metadata 2 | 3 | from .bitrate_stats import BitrateStats, BitrateStatsSummary, run_command 4 | 5 | __version__ = importlib.metadata.version("ffmpeg_bitrate_stats") 6 | 7 | __all__ = ["BitrateStats", "BitrateStatsSummary", "run_command"] 8 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/astral-sh/ruff-pre-commit 3 | rev: v0.12.11 4 | hooks: 5 | - id: ruff 6 | args: [--fix] 7 | - id: ruff-format 8 | - repo: https://github.com/commitizen-tools/commitizen 9 | rev: v4.1.0 10 | hooks: 11 | - id: commitizen 12 | stages: [commit-msg] 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Features and Bugfixes 2 | 3 | If you want to contribute a new feature or fix, please: 4 | 5 | - Check if there isn't any open issue for the same problem 6 | - Fork the project 7 | - Implement your feature or fix 8 | - Bonus points if you provide a test case in `test/test.py` 9 | - Provide a commit for the change you want to make (one feature per commit, please) 10 | - Create a pull request 11 | 12 | ## Issues and Questions 13 | 14 | If you simply have a question or want to raise an issue, head to the issue tracker. There's a template there that you're kindly asked to fill out. It helps me understand what the problem might be. -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.2.0] - 2025-12-02 2 | 3 | ### 🚀 Features 4 | 5 | - Add progress 6 | 7 | ### ⚙️ Miscellaneous Tasks 8 | 9 | - Remove gitchangelog files 10 | - Bump version to 1.2.0 11 | ## [1.1.4] - 2025-10-17 12 | 13 | ### ⚙️ Miscellaneous Tasks 14 | 15 | - Add commitizen for conventional commits 16 | - Add python 3.14 support, remove old license classifier 17 | - Bump version to 1.1.4 18 | ## [1.1.2] - 2024-11-14 19 | 20 | ### 🐛 Bug Fixes 21 | 22 | - Only add read_intervals option if needed 23 | ## [1.1.1] - 2024-11-04 24 | 25 | ### 📚 Documentation 26 | 27 | - Add GabrielChanzy as a contributor for code (#12) 28 | ## [0.0.1] - 2019-04-19 29 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitType": "docs", 8 | "commitConvention": "angular", 9 | "contributors": [ 10 | { 11 | "login": "GabrielChanzy", 12 | "name": "GabrielChanzy", 13 | "avatar_url": "https://avatars.githubusercontent.com/u/43713708?v=4", 14 | "profile": "https://github.com/GabrielChanzy", 15 | "contributions": [ 16 | "code" 17 | ] 18 | } 19 | ], 20 | "contributorsPerLine": 7, 21 | "skipCi": true, 22 | "repoType": "github", 23 | "repoHost": "https://github.com", 24 | "projectName": "ffmpeg-bitrate-stats", 25 | "projectOwner": "slhck" 26 | } 27 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: slhck # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: I want to suggest an idea for this project 4 | 5 | --- 6 | 7 | **:warning: Please read this carefully and edit the example responses! If you do not fill out this information, your feature request may be closed without comment.** 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. E.g. “I'm always frustrated when [...]” 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | name: Test Package 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | python-version: ["3.9", "3.14"] 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Install uv 19 | uses: astral-sh/setup-uv@v3 20 | - name: Set up Python ${{ matrix.python-version }} 21 | run: uv python install ${{ matrix.python-version }} 22 | - name: Install ffmpeg 23 | run: | 24 | sudo apt-get update -y 25 | sudo apt-get install -y ffmpeg 26 | - name: Install dependencies 27 | run: | 28 | uv sync --group dev 29 | - name: Lint with ruff 30 | run: | 31 | uv run ruff check . 32 | uv run ruff format --check . 33 | - name: Type check with mypy 34 | run: | 35 | uv run mypy . 36 | - name: Test with pytest 37 | run: | 38 | uv run pytest 39 | -------------------------------------------------------------------------------- /src/ffmpeg_bitrate_stats/log.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | class CustomLogFormatter(logging.Formatter): 5 | """ 6 | https://stackoverflow.com/a/56944256/435093 7 | """ 8 | 9 | grey = "\x1b[38;20m" 10 | yellow = "\x1b[33;20m" 11 | red = "\x1b[31;20m" 12 | bold_red = "\x1b[31;1m" 13 | reset = "\x1b[0m" 14 | # strformat = ( 15 | # "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" 16 | # ) 17 | strformat = "%(levelname)s - %(message)s" 18 | 19 | FORMATS = { 20 | logging.DEBUG: grey + strformat + reset, 21 | logging.INFO: grey + strformat + reset, 22 | logging.WARNING: yellow + strformat + reset, 23 | logging.ERROR: red + strformat + reset, 24 | logging.CRITICAL: bold_red + strformat + reset, 25 | } 26 | 27 | def format(self, record: logging.LogRecord) -> str: 28 | log_fmt = self.FORMATS.get(record.levelno) 29 | formatter = logging.Formatter(log_fmt) 30 | return formatter.format(record) 31 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ffmpeg_bitrate_stats, Copyright (c) 2019-2023 Werner Robitza 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: I ran across an error or bug in the program 4 | 5 | --- 6 | 7 | **:warning: Please read this carefully and edit the example responses! If you do not fill out this information, your bug report may be closed without comment.** 8 | 9 | **Checklist** (please tick all boxes) 10 | - [ ] I am using the latest version of `ffmpeg-bitrate-stats` (run `pip3 install --upgrade ffmpeg-bitrate-stats`) 11 | - [ ] I am using the latest stable version of `ffmpeg` or a recent build from Git master 12 | 13 | **Expected behavior** 14 | A clear and concise description of what you expected to happen. 15 | 16 | **Actual behavior** 17 | What happened? 18 | 19 | **Command** 20 | The exact command you were trying to run: 21 | 22 | ``` 23 | 24 | ``` 25 | 26 | Any output you get when running the command with the `-v` flag: 27 | 28 | ``` 29 | 30 | ``` 31 | 32 | **Environment (please complete the following information):** 33 | - [ ] Your operating system 34 | - [ ] Your Python version / distribution (`python3 --version` or `python --version`) 35 | - [ ] Your ffmpeg version (`ffmpeg -version`) 36 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["uv_build>=0.8.14,<0.9.0"] 3 | build-backend = "uv_build" 4 | 5 | [project] 6 | name = "ffmpeg_bitrate_stats" 7 | version = "1.2.0" 8 | description = "Calculate bitrate statistics using FFmpeg" 9 | readme = "README.md" 10 | authors = [ 11 | { name = "Werner Robitza", email = "werner.robitza@gmail.com" } 12 | ] 13 | license = "MIT" 14 | license-files = ["LICENSE.md"] 15 | requires-python = ">=3.9" 16 | classifiers = [ 17 | "Development Status :: 4 - Beta", 18 | "Intended Audience :: Developers", 19 | "Topic :: Multimedia :: Video", 20 | "Programming Language :: Python :: 3", 21 | "Programming Language :: Python :: 3.9", 22 | "Programming Language :: Python :: 3.10", 23 | "Programming Language :: Python :: 3.11", 24 | "Programming Language :: Python :: 3.12", 25 | "Programming Language :: Python :: 3.13", 26 | "Programming Language :: Python :: 3.14", 27 | ] 28 | dependencies = [ 29 | "numpy", 30 | "pandas", 31 | "plotille", 32 | "tqdm", 33 | ] 34 | 35 | [project.urls] 36 | Homepage = "https://github.com/slhck/ffmpeg-bitrate-stats" 37 | Repository = "https://github.com/slhck/ffmpeg-bitrate-stats" 38 | 39 | [project.scripts] 40 | ffmpeg-bitrate-stats = "ffmpeg_bitrate_stats.__main__:main" 41 | 42 | [dependency-groups] 43 | dev = [ 44 | "pytest >=8.1.1,<9", 45 | "ruff>=0.12.11", 46 | "mypy", 47 | "pdoc>=15.0.4", 48 | ] 49 | 50 | [tool.mypy] 51 | python_version = "3.13" 52 | ignore_missing_imports = true 53 | exclude = ["build"] 54 | namespace_packages = false 55 | 56 | -------------------------------------------------------------------------------- /tests/test_ffmpeg_bitrate_stats.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pytest 2 | 3 | import json 4 | import os 5 | import sys 6 | 7 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) 8 | 9 | from ffmpeg_bitrate_stats import run_command # noqa: E402 10 | 11 | test_files = { 12 | "test.mp4": { 13 | "params": [], 14 | "results": { 15 | "stream_type": "video", 16 | "avg_fps": 25.0, 17 | "num_frames": 25, 18 | "avg_bitrate": 58.944, 19 | "avg_bitrate_over_chunks": 61.4, 20 | "max_bitrate": 61.4, 21 | "min_bitrate": 61.4, 22 | "max_bitrate_factor": 1.042, 23 | "bitrate_per_chunk": [61.4], 24 | "aggregation": "time", 25 | "chunk_size": 1.0, 26 | "duration": 1.0, 27 | }, 28 | }, 29 | "without_timestamps.mp4": { 30 | "params": [], 31 | "results": { 32 | "stream_type": "video", 33 | "avg_fps": 25.0, 34 | "num_frames": 25, 35 | "avg_bitrate": 111.128, 36 | "avg_bitrate_over_chunks": 115.758, 37 | "max_bitrate": 115.758, 38 | "min_bitrate": 115.758, 39 | "max_bitrate_factor": 1.042, 40 | "bitrate_per_chunk": [115.758], 41 | "aggregation": "time", 42 | "chunk_size": 1.0, 43 | "duration": 1.0, 44 | }, 45 | }, 46 | "test_keyframes.mp4": { 47 | "params": ["-a", "gop"], 48 | "results": { 49 | "stream_type": "video", 50 | "avg_fps": 50.0, 51 | "num_frames": 5, 52 | "avg_bitrate": 14813.6, 53 | "avg_bitrate_over_chunks": 9258.5, 54 | "max_bitrate": 9258.5, 55 | "min_bitrate": 9258.5, 56 | "max_bitrate_factor": 0.625, 57 | "bitrate_per_chunk": [9258.5], 58 | "aggregation": "gop", 59 | "chunk_size": None, 60 | "duration": 0.1, 61 | }, 62 | }, 63 | } 64 | 65 | 66 | class TestBitrates: 67 | def test_output(self) -> None: 68 | """ 69 | Simple test for CLI functionality 70 | """ 71 | 72 | for test_filename, expected_output in test_files.items(): 73 | test_file = os.path.abspath( 74 | os.path.join(os.path.dirname(__file__), test_filename) 75 | ) 76 | 77 | stdout, _ = run_command( 78 | [ 79 | "python3", 80 | "-m", 81 | "ffmpeg_bitrate_stats", 82 | test_file, 83 | *expected_output["params"], 84 | ] 85 | ) 86 | 87 | assert stdout is not None 88 | 89 | output = json.loads(stdout) 90 | 91 | assert test_filename in output["input_file"] 92 | 93 | del output["input_file"] 94 | 95 | assert output == expected_output["results"] 96 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | .vscode 163 | -------------------------------------------------------------------------------- /src/ffmpeg_bitrate_stats/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Calculate bitrate stats from video 4 | # 5 | # Output is in kilobit per second unless specified otherwise. 6 | # 7 | # Author: Werner Robitza 8 | # License: MIT 9 | 10 | import argparse 11 | import logging 12 | import os 13 | import sys 14 | from typing import Tuple 15 | 16 | from .__init__ import __version__ as version 17 | from .bitrate_stats import BitrateStats 18 | from .log import CustomLogFormatter 19 | 20 | logger = logging.getLogger("ffmpeg-bitrate-stats") 21 | 22 | 23 | def get_terminal_size() -> Tuple[int, int]: 24 | try: 25 | term_size = os.get_terminal_size() 26 | return (term_size.columns, term_size.lines) 27 | except OSError: 28 | return (80, 24) 29 | 30 | 31 | def setup_logger(level: int = logging.INFO) -> logging.Logger: 32 | logger = logging.getLogger("ffmpeg-bitrate-stats") 33 | logger.setLevel(level) 34 | 35 | ch = logging.StreamHandler(sys.stderr) 36 | ch.setLevel(level) 37 | 38 | ch.setFormatter(CustomLogFormatter()) 39 | 40 | logger.addHandler(ch) 41 | 42 | return logger 43 | 44 | 45 | def main() -> None: 46 | parser = argparse.ArgumentParser( 47 | formatter_class=argparse.ArgumentDefaultsHelpFormatter, 48 | description="ffmpeg_bitrate_stats v" + version, 49 | ) 50 | parser.add_argument("input", help="input file") 51 | 52 | parser.add_argument( 53 | "-n", 54 | "--dry-run", 55 | action="store_true", 56 | help="Do not run command, just show what would be done", 57 | ) 58 | 59 | parser.add_argument( 60 | "-v", "--verbose", action="store_true", help="Show verbose output" 61 | ) 62 | 63 | parser.add_argument( 64 | "-q", 65 | "--quiet", 66 | action="store_true", 67 | help="Do not show progress bar", 68 | ) 69 | 70 | parser.add_argument( 71 | "-s", 72 | "--stream-type", 73 | default="video", 74 | choices=["video", "audio"], 75 | help="Stream type to analyze", 76 | ) 77 | 78 | parser.add_argument( 79 | "-a", 80 | "--aggregation", 81 | default="time", 82 | choices=["time", "gop"], 83 | help="Window for aggregating statistics, either time-based (per-second) or per GOP", 84 | ) 85 | 86 | parser.add_argument( 87 | "-c", 88 | "--chunk-size", 89 | type=float, 90 | default=1.0, 91 | help="Custom aggregation window size in seconds", 92 | ) 93 | 94 | parser.add_argument( 95 | "-rs", 96 | "--read-start", 97 | type=str, 98 | default=None, 99 | help="Time to wait before sampling video (in HH:MM:SS.msec or seconds)", 100 | ) 101 | parser.add_argument( 102 | "-rd", 103 | "--read-duration", 104 | type=str, 105 | default=None, 106 | help="Duration for sampling stream (in HH:MM:SS.msec or seconds). Note that seeking is not accurate, see ffprobe documentation on '-read_intervals'.", 107 | ) 108 | 109 | parser.add_argument( 110 | "-of", 111 | "--output-format", 112 | type=str, 113 | default="json", 114 | choices=["json", "csv"], 115 | help="output in which format", 116 | ) 117 | 118 | parser.add_argument( 119 | "-p", 120 | "--plot", 121 | action="store_true", 122 | help="Plot the bitrate over time (to STDERR)", 123 | ) 124 | 125 | parser.add_argument( 126 | "-pw", 127 | "--plot-width", 128 | type=int, 129 | default=max(get_terminal_size()[0] - 10, 10), 130 | help="Plot width", 131 | ) 132 | parser.add_argument( 133 | "-ph", 134 | "--plot-height", 135 | type=int, 136 | default=max(get_terminal_size()[1] - 6, 10), 137 | help="Plot height", 138 | ) 139 | 140 | cli_args = parser.parse_args() 141 | 142 | setup_logger(logging.DEBUG if cli_args.verbose else logging.INFO) 143 | 144 | # Show progress by default, but not when quiet or verbose mode is enabled 145 | show_progress = not cli_args.quiet and not cli_args.verbose 146 | 147 | br = BitrateStats( 148 | cli_args.input, 149 | stream_type=cli_args.stream_type, 150 | aggregation=cli_args.aggregation, 151 | chunk_size=cli_args.chunk_size, 152 | read_start=cli_args.read_start, 153 | read_duration=cli_args.read_duration, 154 | dry_run=cli_args.dry_run, 155 | show_progress=show_progress, 156 | ) 157 | br.calculate_statistics() 158 | 159 | br.print_statistics(cli_args.output_format) 160 | 161 | if cli_args.plot: 162 | br.plot( 163 | width=cli_args.plot_width, 164 | height=cli_args.plot_height, 165 | ) 166 | 167 | 168 | if __name__ == "__main__": 169 | main() 170 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FFmpeg Bitrate Stats 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) 4 | 5 | 6 | [![PyPI version](https://img.shields.io/pypi/v/ffmpeg_bitrate_stats.svg)](https://pypi.org/project/ffmpeg_bitrate_stats) 7 | 8 | [![Python package](https://github.com/slhck/ffmpeg-bitrate-stats/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/ffmpeg-bitrate-stats/actions/workflows/python-package.yml) 9 | 10 | Simple script for calculating bitrate statistics using FFmpeg. 11 | 12 | Author: Werner Robitza 13 | 14 | **Note:** Previous versions installed a `ffmpeg_bitrate_stats` executable. To harmonize it with other tools, now the executable is called `ffmpeg-bitrate-stats`. Please ensure you remove the old executable (e.g. run `which ffmpeg_bitrate_stats` and remove the file). 15 | 16 | Contents: 17 | 18 | - [Requirements](#requirements) 19 | - [Installation](#installation) 20 | - [Usage](#usage) 21 | - [Output](#output) 22 | - [Plotting](#plotting) 23 | - [API](#api) 24 | - [Contributors](#contributors) 25 | - [License](#license) 26 | 27 | ------ 28 | 29 | ## Requirements 30 | 31 | - Python 3.9 or higher 32 | - FFmpeg: 33 | - download a static build from [their website](http://ffmpeg.org/download.html) 34 | - put the `ffprobe` executable in your `$PATH` 35 | 36 | ## Installation 37 | 38 | Simply run it via [uv](https://docs.astral.sh/uv/getting-started/installation/): 39 | 40 | ```bash 41 | uvx ffmpeg-bitrate-stats 42 | ``` 43 | 44 | Or install via [pipx](https://pipx.pypa.io/latest/installation/). 45 | Or with pip: 46 | 47 | ```bash 48 | pip3 install --user ffmpeg_bitrate_stats 49 | ``` 50 | 51 | ## Usage 52 | 53 | The script outputs a bunch of bitrate statistics, including aggregations for pre-defined windows. These windows can either be time-based or GOP-based (for video streams). When choosing a time-based window, you can specify the size of the chunks in seconds. 54 | 55 | Output is to STDOUT so you can redirect that to a file or another script. 56 | 57 | See `ffmpeg-bitrate-stats -h`: 58 | 59 | ``` 60 | usage: __main__.py [-h] [-n] [-v] [-q] [-s {video,audio}] [-a {time,gop}] 61 | [-c CHUNK_SIZE] [-rs READ_START] [-rd READ_DURATION] 62 | [-of {json,csv}] [-p] [-pw PLOT_WIDTH] [-ph PLOT_HEIGHT] 63 | input 64 | 65 | ffmpeg_bitrate_stats v1.1.4 66 | 67 | positional arguments: 68 | input input file 69 | 70 | options: 71 | -h, --help show this help message and exit 72 | -n, --dry-run Do not run command, just show what would be done 73 | (default: False) 74 | -v, --verbose Show verbose output (default: False) 75 | -q, --quiet Do not show progress bar (default: False) 76 | -s, --stream-type {video,audio} 77 | Stream type to analyze (default: video) 78 | -a, --aggregation {time,gop} 79 | Window for aggregating statistics, either time-based 80 | (per-second) or per GOP (default: time) 81 | -c, --chunk-size CHUNK_SIZE 82 | Custom aggregation window size in seconds (default: 83 | 1.0) 84 | -rs, --read-start READ_START 85 | Time to wait before sampling video (in HH:MM:SS.msec 86 | or seconds) (default: None) 87 | -rd, --read-duration READ_DURATION 88 | Duration for sampling stream (in HH:MM:SS.msec or 89 | seconds). Note that seeking is not accurate, see 90 | ffprobe documentation on '-read_intervals'. (default: 91 | None) 92 | -of, --output-format {json,csv} 93 | output in which format (default: json) 94 | -p, --plot Plot the bitrate over time (to STDERR) (default: 95 | False) 96 | -pw, --plot-width PLOT_WIDTH 97 | Plot width (default: 70) 98 | -ph, --plot-height PLOT_HEIGHT 99 | Plot height (default: 18) 100 | ``` 101 | 102 | By default, a progress bar is shown during analysis. Use `-q`/`--quiet` to disable it, or `-v`/`--verbose` to show debug output instead. 103 | 104 | ## Output 105 | 106 | The output can be JSON, which includes individual fields for each chunk, or CSV, which repeats each line for each chunk. The CSV adheres to the “tidy” data concept, so it's a little redundant. 107 | 108 | Rates are given in kilobit per second, using SI prefixes (i.e., kilo = 1000). 109 | 110 | Explanation of the fields: 111 | 112 | - `input_file`: Path to the input file 113 | - `stream_type`: Type of stream used (video, audio) 114 | - `avg_fps`: Average FPS (number of frames divided by duration) 115 | - `num_frames`: Number of frames 116 | - `avg_bitrate`: Average bitrate 117 | - `avg_bitrate_over_chunks`: Average bitrate calculated over the chunks 118 | - `max_bitrate`: Maximum bitrate calculated over the chunks 119 | - `min_bitrate`: Minimum bitrate calculated over the chunks 120 | - `max_bitrate_factor`: Relation between peak and average 121 | - `bitrate_per_chunk`: Individual bitrates for each chunk 122 | - `aggregation`: Type of aggregation used 123 | - `chunk_size`: Size of the chunk (when aggregation is "time") 124 | - `duration`: Total duration of the stream. It is the sum of all frame durations, where each frame's duration is either based on `duration_time` field in ffmpeg, or the difference between the current and previous frame's PTS. 125 | 126 | JSON example: 127 | 128 | ```bash 129 | ffmpeg-bitrate-stats -a time -c 30 -of json BigBuckBunny.mp4 130 | ``` 131 | 132 | This returns: 133 | 134 | ```json 135 | { 136 | "input_file": "BigBuckBunny.mp4", 137 | "stream_type": "video", 138 | "avg_fps": 60.002, 139 | "num_frames": 38072, 140 | "avg_bitrate": 8002.859, 141 | "avg_bitrate_over_chunks": 7849.263, 142 | "max_bitrate": 14565.117, 143 | "min_bitrate": 3876.533, 144 | "max_bitrate_factor": 1.82, 145 | "bitrate_per_chunk": [ 146 | 8960.89, 147 | 8036.678, 148 | 6099.959, 149 | 4247.879, 150 | 7276.979, 151 | 5738.383, 152 | 7740.339, 153 | 7881.705, 154 | 7572.594, 155 | 8387.719, 156 | 9634.343, 157 | 9939.488, 158 | 9365.104, 159 | 5061.071, 160 | 14565.117, 161 | 9725.483, 162 | 4573.873, 163 | 7765.041, 164 | 9796.135, 165 | 12524.024, 166 | 3876.533, 167 | 3914.455 168 | ], 169 | "aggregation": "time", 170 | "chunk_size": 30.0, 171 | "duration": 634.517 172 | } 173 | ``` 174 | 175 | CSV example: 176 | 177 | ``` 178 | ➜ ffmpeg-bitrate-stats -a time -c 30 -of csv BigBuckBunny.mp4 179 | input_file,chunk_index,stream_type,avg_fps,num_frames,avg_bitrate,avg_bitrate_over_chunks,max_bitrate,min_bitrate,max_bitrate_factor,bitrate_per_chunk,aggregation,chunk_size,duration 180 | BigBuckBunny.mp4,0,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,8960.89,time,30.0,634.517 181 | BigBuckBunny.mp4,1,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,8036.678,time,30.0,634.517 182 | BigBuckBunny.mp4,2,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,6099.959,time,30.0,634.517 183 | BigBuckBunny.mp4,3,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,4247.879,time,30.0,634.517 184 | BigBuckBunny.mp4,4,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,7276.979,time,30.0,634.517 185 | BigBuckBunny.mp4,5,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,5738.383,time,30.0,634.517 186 | BigBuckBunny.mp4,6,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,7740.339,time,30.0,634.517 187 | BigBuckBunny.mp4,7,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,7881.705,time,30.0,634.517 188 | BigBuckBunny.mp4,8,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,7572.594,time,30.0,634.517 189 | BigBuckBunny.mp4,9,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,8387.719,time,30.0,634.517 190 | BigBuckBunny.mp4,10,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,9634.343,time,30.0,634.517 191 | BigBuckBunny.mp4,11,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,9939.488,time,30.0,634.517 192 | BigBuckBunny.mp4,12,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,9365.104,time,30.0,634.517 193 | BigBuckBunny.mp4,13,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,5061.071,time,30.0,634.517 194 | BigBuckBunny.mp4,14,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,14565.117,time,30.0,634.517 195 | BigBuckBunny.mp4,15,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,9725.483,time,30.0,634.517 196 | BigBuckBunny.mp4,16,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,4573.873,time,30.0,634.517 197 | BigBuckBunny.mp4,17,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,7765.041,time,30.0,634.517 198 | BigBuckBunny.mp4,18,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,9796.135,time,30.0,634.517 199 | BigBuckBunny.mp4,19,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,12524.024,time,30.0,634.517 200 | BigBuckBunny.mp4,20,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,3876.533,time,30.0,634.517 201 | BigBuckBunny.mp4,21,video,60.002,38072,8002.859,7849.263,14565.117,3876.533,1.82,3914.455,time,30.0,634.517 202 | ``` 203 | 204 | ## Plotting 205 | 206 | To enable plots, pass the `-p` or `--plot` flag. This will plot the bitrate over time to STDERR. You can redirect this to a file, or pipe it to another program. Or you can disable STDOUT output with `>/dev/null` to only see the plot: 207 | 208 | ```bash 209 | ffmpeg-bitrate-stats -a time -c 30 -p BigBuckBunny.mp4 >/dev/null 210 | ``` 211 | 212 | This might output a plot like this: 213 | 214 | ```console 215 | 7474.000 | 216 | 6975.733 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 217 | 6477.467 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 218 | 5979.200 | ⡇⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠈⡆⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 219 | 5480.933 | ⡧⡀⠀⠀⢰⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠁⠀⠀⠱⠊⠱⡀⠀⠀⠀⠀⢀⠤⡀⠀⠀⠀⠀⠀⠀⢀⡄⠀⠀⢠⠊⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 220 | 4982.667 | ⡇⠈⢆⠀⡜⠀⢣⠀⠀⠀⠀⠀⠀⡠⠒⠙⡄⠀⠀⡀⠀⠀⢀⡀⠀⢠⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠀⠀⠀⠀⠀⢣⠀⢀⣀⠤⠊⠀⠈⠑⠢⢄⠀⠀⢠⠊⠘⡄⡰⠁⠀⠀⠈⢢⠀⠀⠀⣀⠤⠤⡀⠀⠀⠀⠀ 221 | 4484.400 | ⡇⠀⠈⢶⠁⠀⠈⠦⣀⠀⠀⠀⡔⠁⠀⠀⠱⡀⢰⠙⡄⢀⠎⠈⠒⠁⠀⠱⡀⠀⠀⠀⢠⠓⡄⢀⠤⡀⢰⠁⠀⠀⠀⠀⠀⠀⠀⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠁⠀⠀⠘⠁⠀⠀⠀⠀⠀⠑⠒⠊⠀⠀⠀⠈⠢⠤⡄⠀ 222 | 3986.133 | ⡇⠀⠀⠀⠀⠀⠀⠀⠈⢢⠀⡸⠀⠀⠀⠀⠀⢣⠃⠀⠘⠎⠀⠀⠀⠀⠀⠀⠈⢆⡀⠀⡎⠀⠈⠁⠀⠱⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱⠀ 223 | 3487.867 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠈⢢⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠚⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄ 224 | 2989.600 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇ 225 | 2491.333 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸ 226 | 1993.067 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈ 227 | 1494.800 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 228 | 996.533 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 229 | 498.267 | ⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 230 | 0.000 | ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀ 231 | -----------|-|---------|---------|---------|---------|---------|---------|---------|---------|-> (Time (s)) 232 | | 0.000 5.760 11.520 17.280 23.040 28.800 34.560 40.320 46.080 233 | ``` 234 | 235 | ## API 236 | 237 | The program exposes an API that you can use yourself: 238 | 239 | ```python 240 | from ffmpeg_bitrate_stats import BitrateStats 241 | 242 | ffbs = BitrateStats("path/to/ref") 243 | ffbs.calculate_statistics() 244 | ffbs.print_statistics() 245 | ``` 246 | 247 | For more usage please read [the docs](https://htmlpreview.github.io/?https://github.com/slhck/ffmpeg-bitrate-stats/blob/master/docs/ffmpeg_bitrate_stats.html). 248 | 249 | ## Contributors 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 |
GabrielChanzy
GabrielChanzy

💻
261 | 262 | 263 | 264 | 265 | 266 | 267 | ## License 268 | 269 | ffmpeg_bitrate_stats, Copyright (c) 2019-2023 Werner Robitza 270 | 271 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 272 | 273 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 274 | 275 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 276 | -------------------------------------------------------------------------------- /src/ffmpeg_bitrate_stats/bitrate_stats.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import json 4 | import logging 5 | import math 6 | import subprocess 7 | import sys 8 | from typing import Any, List, Literal, Optional, TypedDict, cast 9 | 10 | import numpy as np 11 | import pandas as pd 12 | import plotille 13 | from tqdm import tqdm 14 | 15 | logger = logging.getLogger("ffmpeg-bitrate-stats") 16 | 17 | 18 | def run_command( 19 | cmd: List[str], 20 | dry_run: bool = False, 21 | show_progress: bool = False, 22 | total_frames: Optional[int] = None, 23 | ) -> tuple[str, str] | tuple[None, None]: 24 | """ 25 | Run a command directly 26 | 27 | Args: 28 | cmd: The command to run 29 | dry_run: If True, just print the command without running 30 | show_progress: If True, show a progress bar 31 | total_frames: Total number of frames for progress estimation 32 | """ 33 | 34 | # for verbose mode 35 | logger.debug("[cmd] " + " ".join(cmd)) 36 | 37 | if dry_run: 38 | logger.info("[cmd] " + " ".join(cmd)) 39 | return None, None 40 | 41 | process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 42 | 43 | if show_progress: 44 | # Read stdout line by line and show progress 45 | stdout_lines: List[str] = [] 46 | packet_count = 0 47 | 48 | # Create progress bar - if we have frame count use it, otherwise use indeterminate 49 | pbar = tqdm( 50 | total=total_frames, 51 | desc="Analyzing", 52 | unit=" packets", 53 | file=sys.stderr, 54 | leave=False, 55 | ) 56 | 57 | assert process.stdout is not None 58 | for line in process.stdout: 59 | decoded_line = line.decode("utf-8") 60 | stdout_lines.append(decoded_line) 61 | # Count packet entries in JSON output 62 | if '"pts_time"' in decoded_line or '"size"' in decoded_line: 63 | packet_count += 1 64 | if total_frames: 65 | pbar.update(1) 66 | else: 67 | pbar.update(1) 68 | pbar.total = packet_count 69 | 70 | pbar.close() 71 | stdout = "".join(stdout_lines) 72 | stderr = process.stderr.read().decode("utf-8") if process.stderr else "" 73 | process.wait() 74 | else: 75 | stdout_bytes, stderr_bytes = process.communicate() 76 | stdout = stdout_bytes.decode("utf-8") 77 | stderr = stderr_bytes.decode("utf-8") 78 | 79 | if process.returncode == 0: 80 | return stdout, stderr 81 | else: 82 | logger.error("error running command: {}".format(" ".join(cmd))) 83 | logger.error(stderr) 84 | sys.exit(1) 85 | 86 | 87 | StreamType = Literal["audio", "video"] 88 | Aggregation = Literal["time", "gop"] 89 | 90 | 91 | class FrameEntry(TypedDict): 92 | n: int 93 | frame_type: Literal["I", "Non-I"] 94 | pts: float | Literal["NaN"] 95 | size: int 96 | duration: float | Literal["NaN"] 97 | 98 | 99 | class BitrateStatsSummary(TypedDict): 100 | input_file: str 101 | """ 102 | The input file. 103 | """ 104 | stream_type: StreamType 105 | """ 106 | The stream type (audio/video). 107 | """ 108 | avg_fps: float 109 | """ 110 | The average FPS. 111 | """ 112 | num_frames: int 113 | """ 114 | The number of frames. 115 | """ 116 | avg_bitrate: float 117 | """ 118 | The average bitrate in kbit/s. 119 | """ 120 | avg_bitrate_over_chunks: float 121 | """ 122 | The average bitrate in kbit/s over chunks. 123 | """ 124 | max_bitrate: float 125 | """ 126 | The maximum bitrate in kbit/s. 127 | """ 128 | min_bitrate: float 129 | """ 130 | The minimum bitrate in kbit/s. 131 | """ 132 | max_bitrate_factor: float 133 | """ 134 | Relation between peak and average. 135 | """ 136 | bitrate_per_chunk: list[float] 137 | """ 138 | The bitrate per chunk in kbit/s. 139 | """ 140 | aggregation: Aggregation 141 | """ 142 | The aggregation type (time/chunks). 143 | """ 144 | chunk_size: Optional[int] 145 | """ 146 | The chunk size in seconds. 147 | """ 148 | duration: float 149 | """ 150 | The duration in seconds. 151 | """ 152 | 153 | 154 | class BitrateStats: 155 | """ 156 | Initialize the BitrateStats class. 157 | 158 | Args: 159 | input_file (str): Path to the input file 160 | stream_type (str, optional): Stream type (audio/video). Defaults to "video". 161 | aggregation (str, optional): Aggregation type (time/gop). Defaults to "time". 162 | chunk_size (int, optional): Chunk size. Defaults to 1. 163 | read_start (str, optional): Start time for reading in HH:MM:SS.msec or seconds. Defaults to None. 164 | read_duration (str, optional): Duration for reading in HH:MM:SS.msec or seconds. Defaults to None. 165 | dry_run (bool, optional): Dry run. Defaults to False. 166 | show_progress (bool, optional): Show progress bar. Defaults to True. 167 | """ 168 | 169 | def __init__( 170 | self, 171 | input_file: str, 172 | stream_type: StreamType = "video", 173 | aggregation: Aggregation = "time", 174 | chunk_size: int = 1, 175 | read_start: Optional[str] = None, 176 | read_duration: Optional[str] = None, 177 | dry_run: bool = False, 178 | show_progress: bool = True, 179 | ): 180 | self.input_file = input_file 181 | 182 | if stream_type not in ["audio", "video"]: 183 | raise ValueError("Stream type must be audio/video") 184 | self.stream_type: StreamType = stream_type 185 | 186 | if aggregation not in ["time", "gop"]: 187 | raise ValueError("Wrong aggregation type") 188 | if aggregation == "gop" and stream_type == "audio": 189 | raise ValueError("GOP aggregation for audio does not make sense") 190 | self.aggregation: Aggregation = aggregation 191 | 192 | if chunk_size and chunk_size < 0: 193 | raise ValueError("Chunk size must be greater than 0") 194 | self.chunk_size = chunk_size 195 | 196 | self.read_length: Optional[str] = None 197 | if read_start or read_duration: 198 | self.read_length = "{}%{}".format( 199 | f"+{read_start}" if read_start else "", 200 | f"+{read_duration}" if read_duration else "", 201 | ) 202 | 203 | self.dry_run = dry_run 204 | self.show_progress = show_progress 205 | 206 | self.duration: float = 0 207 | self.fps: float = 0 208 | self.max_bitrate: float = 0 209 | self.min_bitrate: float = 0 210 | self.moving_avg_bitrate: list[float] = [] 211 | self.frames: list[FrameEntry] = [] 212 | self.bitrate_stats: BitrateStatsSummary | None = None 213 | 214 | self.rounding_factor: int = 3 215 | 216 | self._gop_start_times: Optional[list[float]] = None 217 | self._chunks: list[float] = [] 218 | 219 | def calculate_statistics(self) -> BitrateStatsSummary: 220 | """ 221 | Calculate the bitrate statistics. 222 | 223 | Raises: 224 | RuntimeError: If an error occurred. 225 | 226 | Returns: 227 | dict: The bitrate statistics summary. 228 | """ 229 | self._calculate_frame_sizes() 230 | self._calculate_duration() 231 | self._calculate_fps() 232 | self._calculate_max_min_bitrate() 233 | self._assemble_bitrate_statistics() 234 | 235 | if self.bitrate_stats is None: 236 | raise RuntimeError("bitrate_stats is None, should not happen") 237 | 238 | return self.bitrate_stats 239 | 240 | def _get_frame_count(self) -> Optional[int]: 241 | """ 242 | Get the total frame/packet count for progress estimation. 243 | 244 | Returns: 245 | int or None: The frame count, or None if unavailable. 246 | """ 247 | cmd = [ 248 | "ffprobe", 249 | "-loglevel", 250 | "error", 251 | "-select_streams", 252 | self.stream_type[0] + ":0", 253 | "-show_entries", 254 | "stream=nb_frames", 255 | "-of", 256 | "default=noprint_wrappers=1:nokey=1", 257 | self.input_file, 258 | ] 259 | 260 | try: 261 | result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) 262 | if result.returncode == 0 and result.stdout.strip(): 263 | return int(result.stdout.strip()) 264 | except (subprocess.TimeoutExpired, ValueError): 265 | pass 266 | return None 267 | 268 | def _calculate_frame_sizes(self) -> list[FrameEntry]: 269 | """ 270 | Get the frame sizes via ffprobe using the -show_packets option. 271 | This includes the NAL headers, of course. 272 | 273 | Returns: 274 | list[dict]: The frame sizes plus some extra info. 275 | """ 276 | logger.debug(f"Calculating frame size from {self.input_file}") 277 | 278 | base_cmd = [ 279 | "ffprobe", 280 | "-loglevel", 281 | "error", 282 | "-select_streams", 283 | self.stream_type[0] + ":0", 284 | ] 285 | 286 | if self.read_length: 287 | base_cmd.extend(["-read_intervals", self.read_length]) 288 | 289 | base_cmd.extend( 290 | [ 291 | "-show_packets", 292 | "-show_entries", 293 | "packet=pts_time,dts_time,duration_time,size,flags", 294 | "-of", 295 | "json", 296 | self.input_file, 297 | ] 298 | ) 299 | 300 | # Get frame count for progress bar (only if showing progress) 301 | frame_count = None 302 | if self.show_progress: 303 | frame_count = self._get_frame_count() 304 | 305 | stdout, _ = run_command( 306 | base_cmd, 307 | self.dry_run, 308 | show_progress=self.show_progress, 309 | total_frames=frame_count, 310 | ) 311 | if self.dry_run or stdout is None: 312 | logger.error("Aborting prematurely, dry-run specified or stdout was empty") 313 | sys.exit(0) 314 | 315 | info = json.loads(stdout)["packets"] 316 | # abort if nothing returned 317 | if not info: 318 | raise RuntimeError( 319 | "No frames returned, please check your input file and the ffprobe output. Run with -v to see the ffprobe command." 320 | ) 321 | 322 | ret: list[FrameEntry] = [] 323 | idx = 1 324 | 325 | default_duration = next( 326 | (x["duration_time"] for x in info if "duration_time" in x.keys()), "NaN" 327 | ) 328 | 329 | for packet_info in info: 330 | frame_type: Literal["I", "Non-I"] = ( 331 | # key frames are marked with a capital K (K_ or K__) in packet flags 332 | "I" if "K" in packet_info["flags"] else "Non-I" 333 | ) 334 | 335 | pts: float | Literal["NaN"] = ( 336 | float(packet_info["pts_time"]) 337 | if "pts_time" in packet_info.keys() 338 | else "NaN" 339 | ) 340 | 341 | duration: float | Literal["NaN"] = ( 342 | float(packet_info["duration_time"]) 343 | if "duration_time" in packet_info.keys() 344 | else float(default_duration) 345 | if default_duration != "NaN" 346 | else "NaN" 347 | ) 348 | 349 | ret.append( 350 | { 351 | "n": idx, 352 | "frame_type": frame_type, 353 | "pts": pts, 354 | "size": int(packet_info["size"]), 355 | "duration": duration, 356 | } 357 | ) 358 | idx += 1 359 | 360 | # fix for missing durations, estimate it via PTS 361 | if default_duration == "NaN": 362 | ret = self._fix_durations(ret) 363 | 364 | # fix missing data in first packet (occurs occassionally when reading streams) 365 | if ret[0]["duration"] == "NaN" and isinstance(ret[1]["duration"], float): 366 | ret[0]["duration"] = ret[1]["duration"] 367 | 368 | if ( 369 | ret[0]["pts"] == "NaN" 370 | and isinstance(ret[1]["pts"], float) 371 | and isinstance(ret[0]["duration"], float) 372 | ): 373 | ret[0]["pts"] = ret[1]["pts"] - ret[0]["duration"] 374 | 375 | self.frames = ret 376 | return ret 377 | 378 | def _fix_durations(self, ret: List[FrameEntry]) -> List[FrameEntry]: 379 | """ 380 | Calculate durations based on delta PTS. 381 | """ 382 | last_duration = None 383 | for i in range(len(ret) - 1): 384 | curr_pts = ret[i]["pts"] 385 | next_pts = ret[i + 1]["pts"] 386 | if curr_pts == "NaN" or next_pts == "NaN": 387 | logger.warning("PTS is NaN, duration/bitrate may be invalid") 388 | continue 389 | if next_pts < curr_pts: 390 | logger.warning( 391 | "Non-monotonically increasing PTS, duration/bitrate may be invalid" 392 | ) 393 | last_duration = next_pts - curr_pts 394 | ret[i]["duration"] = last_duration 395 | if last_duration is not None: 396 | ret[-1]["duration"] = last_duration 397 | return ret 398 | 399 | def _calculate_duration(self) -> float: 400 | """ 401 | Sum of all duration entries. 402 | 403 | Returns: 404 | float: The duration in seconds. 405 | """ 406 | self.duration = sum( 407 | f["duration"] for f in self.frames if f["duration"] != "NaN" 408 | ) 409 | return self.duration 410 | 411 | def _calculate_fps(self) -> float: 412 | """ 413 | FPS = number of frames divided by duration. A rough estimate. 414 | 415 | Returns: 416 | float: The FPS. 417 | """ 418 | self.fps = len(self.frames) / self.duration 419 | return self.fps 420 | 421 | def _collect_chunks(self) -> list[float]: 422 | """ 423 | Collect chunks of a certain aggregation length (in seconds, or GOP). 424 | This is cached. 425 | 426 | Returns: 427 | list[float]: The bitrate values per chunk in kbit/s. 428 | """ 429 | if len(self._chunks): 430 | return self._chunks 431 | 432 | logger.debug("Collecting chunks for bitrate calculation") 433 | 434 | # this is where we will store the stats in buckets 435 | aggregation_chunks: list[list[FrameEntry]] = [] 436 | curr_list: list[FrameEntry] = [] 437 | 438 | self._gop_start_times = [] 439 | 440 | if self.aggregation == "gop": 441 | # collect group of pictures, each one containing all frames belonging to it 442 | for frame in self.frames: 443 | if frame["frame_type"] != "I": 444 | curr_list.append(frame) 445 | if frame["frame_type"] == "I": 446 | if curr_list: 447 | aggregation_chunks.append(curr_list) 448 | curr_list = [frame] 449 | self._gop_start_times.append(float(frame["pts"])) 450 | # flush the last one 451 | aggregation_chunks.append(curr_list) 452 | 453 | else: 454 | # per-time aggregation 455 | agg_time: float = 0 456 | for frame in self.frames: 457 | if agg_time < self.chunk_size: 458 | curr_list.append(frame) 459 | agg_time += float(frame["duration"]) 460 | else: 461 | if curr_list: 462 | aggregation_chunks.append(curr_list) 463 | curr_list = [frame] 464 | agg_time = float(frame["duration"]) 465 | aggregation_chunks.append(curr_list) 466 | 467 | # calculate BR per group 468 | self._chunks = [ 469 | BitrateStats._bitrate_for_frame_list(x) for x in aggregation_chunks 470 | ] 471 | 472 | return self._chunks 473 | 474 | @staticmethod 475 | def _bitrate_for_frame_list(frame_list: list[FrameEntry]) -> float: 476 | """ 477 | Given a list of frames with size and PTS, get the bitrate. 478 | 479 | Args: 480 | frame_list (list): list of frames 481 | 482 | Returns: 483 | float: bitrate in kbit/s 484 | """ 485 | if len(frame_list) < 2: 486 | return math.nan 487 | 488 | # sort frames by PTS in case they are unordered 489 | frame_list.sort(key=lambda x: x["pts"]) 490 | 491 | duration = float(frame_list[-1]["pts"]) - float(frame_list[0]["pts"]) 492 | size = sum(f["size"] for f in frame_list) 493 | bitrate = ((size * 8) / 1000) / duration 494 | 495 | return bitrate 496 | 497 | def _calculate_max_min_bitrate(self) -> tuple[float, float]: 498 | """ 499 | Find the min/max from the chunks. 500 | 501 | Returns: 502 | tuple: max, min bitrate in kbit/s 503 | """ 504 | self.max_bitrate = max(self._collect_chunks()) 505 | self.min_bitrate = min(self._collect_chunks()) 506 | return self.max_bitrate, self.min_bitrate 507 | 508 | def _assemble_bitrate_statistics(self) -> BitrateStatsSummary: 509 | """ 510 | Assemble all pre-calculated statistics plus some simple statistical measures. 511 | 512 | Returns: 513 | dict: bitrate statistics 514 | """ 515 | 516 | self.avg_bitrate = ( 517 | sum(f["size"] for f in self.frames) * 8 / 1000 518 | ) / self.duration 519 | self.avg_bitrate_over_chunks: float = cast( 520 | float, np.mean(self._collect_chunks()) 521 | ) 522 | 523 | self.max_bitrate_factor = self.max_bitrate / self.avg_bitrate 524 | 525 | # output data 526 | ret: BitrateStatsSummary = { 527 | "input_file": self.input_file, 528 | "stream_type": self.stream_type, 529 | "avg_fps": round(self.fps, self.rounding_factor), 530 | "num_frames": len(self.frames), 531 | "avg_bitrate": round(self.avg_bitrate, self.rounding_factor), 532 | "avg_bitrate_over_chunks": round( 533 | self.avg_bitrate_over_chunks, self.rounding_factor 534 | ), 535 | "max_bitrate": round(self.max_bitrate, self.rounding_factor), 536 | "min_bitrate": round(self.min_bitrate, self.rounding_factor), 537 | "max_bitrate_factor": round(self.max_bitrate_factor, self.rounding_factor), 538 | "bitrate_per_chunk": [ 539 | round(b, self.rounding_factor) for b in self._collect_chunks() 540 | ], 541 | "aggregation": self.aggregation, 542 | "chunk_size": self.chunk_size if self.aggregation == "time" else None, 543 | "duration": round(self.duration, self.rounding_factor), 544 | } 545 | 546 | self.bitrate_stats = ret 547 | return self.bitrate_stats 548 | 549 | def print_statistics(self, output_format: Literal["csv", "json"]) -> None: 550 | """ 551 | Print the statistics in the specified format to stdout. 552 | 553 | Args: 554 | output_format: The format to print the statistics in (csv, json) 555 | 556 | Raises: 557 | ValueError: If the output format is invalid 558 | """ 559 | if output_format == "csv": 560 | print(self.get_csv()) 561 | elif output_format == "json": 562 | print(self.get_json()) 563 | else: 564 | raise ValueError("Invalid output format") 565 | 566 | def get_csv(self) -> str: 567 | """ 568 | Get the bitrate statistics as a CSV string. 569 | 570 | Raises: 571 | RuntimeError: If no bitrate statistics are available 572 | 573 | Returns: 574 | str: The bitrate statistics as a CSV string 575 | """ 576 | if not self.bitrate_stats: 577 | raise RuntimeError("No bitrate stats available") 578 | 579 | df = pd.DataFrame(self.bitrate_stats) 580 | df.reset_index(level=0, inplace=True) 581 | df.rename(index=str, columns={"index": "chunk_index"}, inplace=True) 582 | cols = df.columns.tolist() 583 | cols.insert(0, cols.pop(cols.index("input_file"))) 584 | df = df.reindex(columns=cols) 585 | return cast(str, df.to_csv(index=False)) 586 | 587 | def get_json(self) -> str: 588 | """ 589 | Get the bitrate statistics as a JSON string. 590 | 591 | Raises: 592 | RuntimeError: If no bitrate statistics are available 593 | 594 | Returns: 595 | str: The bitrate statistics as a JSON string 596 | """ 597 | if not self.bitrate_stats: 598 | raise RuntimeError("No bitrate stats available") 599 | 600 | return json.dumps(self.bitrate_stats, indent=4) 601 | 602 | def plot(self, width: int = 80, height: int = 30) -> None: 603 | """ 604 | Plot the bitrate over time to STDERR. 605 | 606 | Args: 607 | width (int, optional): Width of the plot. Defaults to 80. 608 | height (int, optional): Height of the plot. Defaults to 30. 609 | """ 610 | chunks = self._collect_chunks() 611 | 612 | fig = plotille.Figure() 613 | fig.width = width 614 | fig.height = height 615 | 616 | def _round_decimals( 617 | val: Any, chars: int, delta: float, left: bool = False 618 | ) -> str: 619 | align = "<" if left else "" 620 | return f"{val:{align}{chars}.{self.rounding_factor}f}" 621 | 622 | x_values = ( 623 | self._gop_start_times 624 | if self.aggregation == "gop" 625 | else [i * self.chunk_size for i in range(len(chunks))] 626 | ) 627 | 628 | fig.register_label_formatter(int, _round_decimals) 629 | fig.register_label_formatter(float, _round_decimals) 630 | fig.set_x_limits(min_=0, max_=self.duration) 631 | fig.set_y_limits(min_=0) 632 | fig.x_label = "Time (s)" 633 | fig.y_label = "Bitrate (kbit/s)" 634 | 635 | fig.plot( 636 | x_values, 637 | chunks, 638 | ) 639 | 640 | print(fig.show(), file=sys.stderr) 641 | -------------------------------------------------------------------------------- /docs/search.js: -------------------------------------------------------------------------------- 1 | window.pdocSearch = (function(){ 2 | /** elasticlunr - http://weixsong.github.io * Copyright (C) 2017 Oliver Nightingale * Copyright (C) 2017 Wei Song * MIT Licensed */!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o

\n"}, "ffmpeg_bitrate_stats.BitrateStats": {"fullname": "ffmpeg_bitrate_stats.BitrateStats", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats", "kind": "class", "doc": "

Initialize the BitrateStats class.

\n\n
Arguments:
\n\n
    \n
  • input_file (str): Path to the input file
  • \n
  • stream_type (str, optional): Stream type (audio/video). Defaults to \"video\".
  • \n
  • aggregation (str, optional): Aggregation type (time/gop). Defaults to \"time\".
  • \n
  • chunk_size (int, optional): Chunk size. Defaults to 1.
  • \n
  • read_start (str, optional): Start time for reading in HH:MM:SS.msec or seconds. Defaults to None.
  • \n
  • read_duration (str, optional): Duration for reading in HH:MM:SS.msec or seconds. Defaults to None.
  • \n
  • dry_run (bool, optional): Dry run. Defaults to False.
  • \n
  • show_progress (bool, optional): Show progress bar. Defaults to True.
  • \n
\n"}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.__init__", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.__init__", "kind": "function", "doc": "

\n", "signature": "(\tinput_file: str,\tstream_type: Literal['audio', 'video'] = 'video',\taggregation: Literal['time', 'gop'] = 'time',\tchunk_size: int = 1,\tread_start: Optional[str] = None,\tread_duration: Optional[str] = None,\tdry_run: bool = False,\tshow_progress: bool = True)"}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.input_file", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.input_file", "kind": "variable", "doc": "

\n"}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.stream_type", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.stream_type", "kind": "variable", "doc": "

\n", "annotation": ": Literal['audio', 'video']"}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.aggregation", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.aggregation", "kind": "variable", "doc": "

\n", "annotation": ": Literal['time', 'gop']"}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.chunk_size", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.chunk_size", "kind": "variable", "doc": "

\n"}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.read_length", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.read_length", "kind": "variable", "doc": "

\n", "annotation": ": Optional[str]"}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.dry_run", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.dry_run", "kind": "variable", "doc": "

\n"}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.show_progress", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.show_progress", "kind": "variable", "doc": "

\n"}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.duration", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.duration", "kind": "variable", "doc": "

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.fps", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.fps", "kind": "variable", "doc": "

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.max_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.max_bitrate", "kind": "variable", "doc": "

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.min_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.min_bitrate", "kind": "variable", "doc": "

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.moving_avg_bitrate", "kind": "variable", "doc": "

\n", "annotation": ": list[float]"}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.frames", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.frames", "kind": "variable", "doc": "

\n", "annotation": ": list[ffmpeg_bitrate_stats.bitrate_stats.FrameEntry]"}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.bitrate_stats", "kind": "variable", "doc": "

\n", "annotation": ": ffmpeg_bitrate_stats.bitrate_stats.BitrateStatsSummary | None"}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.rounding_factor", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.rounding_factor", "kind": "variable", "doc": "

\n", "annotation": ": int"}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.calculate_statistics", "kind": "function", "doc": "

Calculate the bitrate statistics.

\n\n
Raises:
\n\n
    \n
  • RuntimeError: If an error occurred.
  • \n
\n\n
Returns:
\n\n
\n

dict: The bitrate statistics summary.

\n
\n", "signature": "(self) -> ffmpeg_bitrate_stats.bitrate_stats.BitrateStatsSummary:", "funcdef": "def"}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.print_statistics", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.print_statistics", "kind": "function", "doc": "

Print the statistics in the specified format to stdout.

\n\n
Arguments:
\n\n
    \n
  • output_format: The format to print the statistics in (csv, json)
  • \n
\n\n
Raises:
\n\n
    \n
  • ValueError: If the output format is invalid
  • \n
\n", "signature": "(self, output_format: Literal['csv', 'json']) -> None:", "funcdef": "def"}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.get_csv", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.get_csv", "kind": "function", "doc": "

Get the bitrate statistics as a CSV string.

\n\n
Raises:
\n\n
    \n
  • RuntimeError: If no bitrate statistics are available
  • \n
\n\n
Returns:
\n\n
\n

str: The bitrate statistics as a CSV string

\n
\n", "signature": "(self) -> str:", "funcdef": "def"}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.get_json", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.get_json", "kind": "function", "doc": "

Get the bitrate statistics as a JSON string.

\n\n
Raises:
\n\n
    \n
  • RuntimeError: If no bitrate statistics are available
  • \n
\n\n
Returns:
\n\n
\n

str: The bitrate statistics as a JSON string

\n
\n", "signature": "(self) -> str:", "funcdef": "def"}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"fullname": "ffmpeg_bitrate_stats.BitrateStats.plot", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStats.plot", "kind": "function", "doc": "

Plot the bitrate over time to STDERR.

\n\n
Arguments:
\n\n
    \n
  • width (int, optional): Width of the plot. Defaults to 80.
  • \n
  • height (int, optional): Height of the plot. Defaults to 30.
  • \n
\n", "signature": "(self, width: int = 80, height: int = 30) -> None:", "funcdef": "def"}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary", "kind": "class", "doc": "

\n", "bases": "typing.TypedDict"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.input_file", "kind": "variable", "doc": "

The input file.

\n", "annotation": ": str"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.stream_type", "kind": "variable", "doc": "

The stream type (audio/video).

\n", "annotation": ": Literal['audio', 'video']"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.avg_fps", "kind": "variable", "doc": "

The average FPS.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.num_frames", "kind": "variable", "doc": "

The number of frames.

\n", "annotation": ": int"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.avg_bitrate", "kind": "variable", "doc": "

The average bitrate in kbit/s.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.avg_bitrate_over_chunks", "kind": "variable", "doc": "

The average bitrate in kbit/s over chunks.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.max_bitrate", "kind": "variable", "doc": "

The maximum bitrate in kbit/s.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.min_bitrate", "kind": "variable", "doc": "

The minimum bitrate in kbit/s.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.max_bitrate_factor", "kind": "variable", "doc": "

Relation between peak and average.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.bitrate_per_chunk", "kind": "variable", "doc": "

The bitrate per chunk in kbit/s.

\n", "annotation": ": list[float]"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.aggregation", "kind": "variable", "doc": "

The aggregation type (time/chunks).

\n", "annotation": ": Literal['time', 'gop']"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.chunk_size", "kind": "variable", "doc": "

The chunk size in seconds.

\n", "annotation": ": Optional[int]"}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"fullname": "ffmpeg_bitrate_stats.BitrateStatsSummary.duration", "modulename": "ffmpeg_bitrate_stats", "qualname": "BitrateStatsSummary.duration", "kind": "variable", "doc": "

The duration in seconds.

\n", "annotation": ": float"}, "ffmpeg_bitrate_stats.run_command": {"fullname": "ffmpeg_bitrate_stats.run_command", "modulename": "ffmpeg_bitrate_stats", "qualname": "run_command", "kind": "function", "doc": "

Run a command directly

\n\n
Arguments:
\n\n
    \n
  • cmd: The command to run
  • \n
  • dry_run: If True, just print the command without running
  • \n
  • show_progress: If True, show a progress bar
  • \n
  • total_frames: Total number of frames for progress estimation
  • \n
\n", "signature": "(\tcmd: List[str],\tdry_run: bool = False,\tshow_progress: bool = False,\ttotal_frames: Optional[int] = None) -> tuple[str, str] | tuple[None, None]:", "funcdef": "def"}}, "docInfo": {"ffmpeg_bitrate_stats": {"qualname": 0, "fullname": 3, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats": {"qualname": 1, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 147}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 208, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"qualname": 3, "fullname": 6, "annotation": 9, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"qualname": 2, "fullname": 5, "annotation": 9, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"qualname": 2, "fullname": 5, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"qualname": 2, "fullname": 5, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"qualname": 4, "fullname": 7, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"qualname": 2, "fullname": 5, "annotation": 7, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"qualname": 3, "fullname": 6, "annotation": 9, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 27, "bases": 0, "doc": 39}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 45, "bases": 0, "doc": 53}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 14, "bases": 0, "doc": 46}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"qualname": 3, "fullname": 6, "annotation": 0, "default_value": 0, "signature": 14, "bases": 0, "doc": 46}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"qualname": 2, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 48, "bases": 0, "doc": 49}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"qualname": 1, "fullname": 4, "annotation": 0, "default_value": 0, "signature": 0, "bases": 2, "doc": 3}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"qualname": 3, "fullname": 6, "annotation": 9, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 6}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"qualname": 5, "fullname": 8, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 10}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"qualname": 4, "fullname": 7, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"qualname": 4, "fullname": 7, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 9}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"qualname": 2, "fullname": 5, "annotation": 9, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"qualname": 3, "fullname": 6, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 8}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"qualname": 2, "fullname": 5, "annotation": 2, "default_value": 0, "signature": 0, "bases": 0, "doc": 7}, "ffmpeg_bitrate_stats.run_command": {"qualname": 2, "fullname": 5, "annotation": 0, "default_value": 0, "signature": 119, "bases": 0, "doc": 61}}, "length": 38, "save": true}, "index": {"qualname": {"root": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 10, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 22, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 14}}}}}}}}}}}}}}}}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}}}, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}, "p": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}}, "df": 2}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}}, "df": 2}}}}}, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 2}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}}, "df": 1}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 2}}}}}}}}}, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 2}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}}, "df": 1}}}}, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 2}}}}}}}}}}, "v": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 4}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "k": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 3, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 1}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}}}, "s": {"docs": {}, "df": 0, "v": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}}, "df": 1}}, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}}, "df": 1}}}}}}, "d": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}}, "df": 1}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 2}}}}}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}}, "df": 1}}}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 1}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "x": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 3}}, "i": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}}, "df": 2}}, "o": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}}, "df": 1}}}}}}, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2}}}, "j": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 1}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 1}}}}}}, "fullname": {"root": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1, "f": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 38}}}}}, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}, "p": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}}, "df": 2}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}}, "df": 2}}}}}, "a": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 2}}}}}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 38, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 22, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 14}}}}}}}}}}}}}}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 38}, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 2}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}}, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 2}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}}, "df": 1}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}}}, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 2}}}}}}}}}}, "v": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 4}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "k": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 3, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 1}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}}}, "s": {"docs": {}, "df": 0, "v": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}}, "df": 1}}, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}}, "df": 1}}}}}}}}, "l": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}}, "df": 1}}}}}}, "d": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1}}, "df": 1}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 2}}}}}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1}}, "df": 1}}}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 1}}}, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "x": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 3}}, "i": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}}, "df": 2}}, "o": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}}, "df": 1}}}}}}, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2}}}, "j": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 1}}}}, "n": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 1}}}}}}, "annotation": {"root": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 24, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 4}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "[": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 2}}}}, "f": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}}, "df": 1}}}}}}}}}}}, "x": {"2": {"7": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 2}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 2}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 2}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 2}}, "df": 4}, "docs": {}, "df": 0}, "docs": {}, "df": 0}, "a": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 2}}}}, "g": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 2}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "[": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 1}}}}}}}}}}}}, "f": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 11}}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1}}, "df": 1}}}}}}}}}, "f": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}}, "df": 1}}}}}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.4142135623730951}}, "df": 2, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.4142135623730951}}, "df": 2}}}, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 1}}}, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1}}, "df": 1}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}}, "df": 2}}}}}, "default_value": {"root": {"docs": {}, "df": 0}}, "signature": {"root": {"1": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}, "3": {"0": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}, "9": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 3.4641016151377544}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 2}}, "df": 2}, "docs": {}, "df": 0}, "8": {"0": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 12.649110640673518}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 4.47213595499958}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 5.830951894845301}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 3.4641016151377544}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 3.4641016151377544}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 6.324555320336759}, "ffmpeg_bitrate_stats.run_command": {"tf": 9.848857801796104}}, "df": 7, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 3}}}, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 2}}}}, "f": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.7320508075688772}}, "df": 4, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1.4142135623730951}}, "df": 1}}}}, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}, "e": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "f": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 5}}}}, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}, "u": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 1}}}}}, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 2}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}}, "g": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}}}}}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}}}, "g": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "k": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}}, "s": {"docs": {}, "df": 0, "v": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}, "m": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}}}, "n": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.7320508075688772}}, "df": 4}}}}, "d": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}}, "df": 1}}}}}}}, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}, "b": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1.4142135623730951}}, "df": 1, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}}}}}}}}}}}}}}, "p": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}}}}}}, "j": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}, "w": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}}}}}, "h": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}}}}}}}}, "bases": {"root": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1}}, "df": 1}}}}}}}}}}}, "doc": {"root": {"1": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}, "3": {"0": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "8": {"0": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}, "docs": {}, "df": 0}, "docs": {"ffmpeg_bitrate_stats": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats": {"tf": 7.483314773547883}, "ffmpeg_bitrate_stats.BitrateStats.__init__": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.input_file": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.stream_type": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.aggregation": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.chunk_size": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.read_length": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.dry_run": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.show_progress": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.duration": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.fps": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.max_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.min_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.moving_avg_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.frames": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.bitrate_stats": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.rounding_factor": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 4.795831523312719}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 4.898979485566356}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 4.58257569495584}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 4.58257569495584}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 4.58257569495584}, "ffmpeg_bitrate_stats.BitrateStatsSummary": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.run_command": {"tf": 4.898979485566356}}, "df": 38, "i": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 9, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}}}}}}, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}}, "df": 2}, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}}}, "f": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 5}, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 2.23606797749979}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 19}}, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 2.8284271247461903}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 4, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 1}}}}, "y": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 3}}}, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 2, "/": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "p": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}, "c": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "k": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 1}}}}}}}}}}, "r": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 2}}}}, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 9, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}}}}}}}}}, "o": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}, "e": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "w": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 1}}}}}}}, "c": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}}, "h": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "k": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 3, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 1}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}}}, "s": {"docs": {}, "df": 0, "v": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.4142135623730951}}, "df": 2}}, "o": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1.7320508075688772}}, "df": 1}}}}}}, "m": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}, "a": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 3, "r": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 4}}}}}}}, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2}}, "u": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "/": {"docs": {}, "df": 0, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}}}}}}}}, "g": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.aggregation": {"tf": 1}}, "df": 2}}}}}}}}}}, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 1}}, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.4142135623730951}}, "df": 2}, "v": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2}}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 4}}}}}}}, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.input_file": {"tf": 1}}, "df": 2}}}, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 2}}, "df": 1}}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}}, "p": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_fps": {"tf": 1}}, "df": 1}}, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 2}}}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 2.23606797749979}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 3, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.stream_type": {"tf": 1}}, "df": 2}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.4142135623730951}}, "df": 2}}}}, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1.7320508075688772}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.7320508075688772}}, "df": 4}}}}}}}}, "d": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}}, "df": 1}}}}}, "i": {"docs": {}, "df": 0, "z": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}}, "df": 2}}}, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.chunk_size": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 3}}}}}}, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "w": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.4142135623730951}}, "df": 2}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}, "p": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}}}}}}, "p": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.7320508075688772}}, "df": 2}}}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}}, "l": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.7320508075688772}}, "df": 1}}}, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "k": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 1}}, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 1}}}, "o": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "l": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 2.6457513110645907}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}, "c": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "p": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1.4142135623730951}}, "df": 1}}}}}, "v": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}}, "df": 2}}}, "f": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 3}}, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "f": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 2.6457513110645907}, "ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}}, "df": 2}}}}}}}, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.BitrateStatsSummary.duration": {"tf": 1}}, "df": 2}}}}}}}, "r": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}, "i": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "y": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}}}, "v": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1}}, "df": 1}}}}, "a": {"docs": {}, "df": 0, "l": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}}, "df": 1}}}}}}}}}}, "r": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "d": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}}}}, "t": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 3}}}}}, "l": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate_factor": {"tf": 1}}, "df": 1}}}}}}}, "u": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}, "ffmpeg_bitrate_stats.run_command": {"tf": 1.7320508075688772}}, "df": 2, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 3}}}}}}}}}, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "g": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}, "a": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 4}}}}}}, "h": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, ":": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, ":": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}}}}}}, "e": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "g": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}}, "df": 1}}}}}}, "m": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "c": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}}, "a": {"docs": {}, "df": 0, "x": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}}, "df": 1}}}}}}, "i": {"docs": {}, "df": 0, "n": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "m": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}}, "df": 1}}}}}}}, "n": {"docs": {}, "df": 0, "o": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2, "n": {"docs": {}, "df": 0, "e": {"docs": {"ffmpeg_bitrate_stats.BitrateStats": {"tf": 1.4142135623730951}}, "df": 1}}}, "u": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.num_frames": {"tf": 1}, "ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 2}}}}}}, "e": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "r": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "r": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.calculate_statistics": {"tf": 1}}, "df": 1}}}}, "s": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "m": {"docs": {}, "df": 0, "a": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}}}}}, "j": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "n": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.print_statistics": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1.4142135623730951}}, "df": 2}}}, "u": {"docs": {}, "df": 0, "s": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}, "g": {"docs": {}, "df": 0, "e": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.get_csv": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStats.get_json": {"tf": 1}}, "df": 2}}}, "w": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "d": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "h": {"docs": {"ffmpeg_bitrate_stats.BitrateStats.plot": {"tf": 1.4142135623730951}}, "df": 1}}}, "t": {"docs": {}, "df": 0, "h": {"docs": {}, "df": 0, "o": {"docs": {}, "df": 0, "u": {"docs": {}, "df": 0, "t": {"docs": {"ffmpeg_bitrate_stats.run_command": {"tf": 1}}, "df": 1}}}}}}}, "k": {"docs": {}, "df": 0, "b": {"docs": {}, "df": 0, "i": {"docs": {}, "df": 0, "t": {"docs": {}, "df": 0, "/": {"docs": {}, "df": 0, "s": {"docs": {"ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.avg_bitrate_over_chunks": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.max_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.min_bitrate": {"tf": 1}, "ffmpeg_bitrate_stats.BitrateStatsSummary.bitrate_per_chunk": {"tf": 1}}, "df": 5}}}}}}}}}, "pipeline": ["trimmer"], "_isPrebuiltIndex": true}; 4 | 5 | // mirrored in build-search-index.js (part 1) 6 | // Also split on html tags. this is a cheap heuristic, but good enough. 7 | elasticlunr.tokenizer.setSeperator(/[\s\-.;&_'"=,()]+|<[^>]*>/); 8 | 9 | let searchIndex; 10 | if (docs._isPrebuiltIndex) { 11 | console.info("using precompiled search index"); 12 | searchIndex = elasticlunr.Index.load(docs); 13 | } else { 14 | console.time("building search index"); 15 | // mirrored in build-search-index.js (part 2) 16 | searchIndex = elasticlunr(function () { 17 | this.pipeline.remove(elasticlunr.stemmer); 18 | this.pipeline.remove(elasticlunr.stopWordFilter); 19 | this.addField("qualname"); 20 | this.addField("fullname"); 21 | this.addField("annotation"); 22 | this.addField("default_value"); 23 | this.addField("signature"); 24 | this.addField("bases"); 25 | this.addField("doc"); 26 | this.setRef("fullname"); 27 | }); 28 | for (let doc of docs) { 29 | searchIndex.addDoc(doc); 30 | } 31 | console.timeEnd("building search index"); 32 | } 33 | 34 | return (term) => searchIndex.search(term, { 35 | fields: { 36 | qualname: {boost: 4}, 37 | fullname: {boost: 2}, 38 | annotation: {boost: 2}, 39 | default_value: {boost: 2}, 40 | signature: {boost: 2}, 41 | bases: {boost: 2}, 42 | doc: {boost: 1}, 43 | }, 44 | expand: true 45 | }); 46 | })(); --------------------------------------------------------------------------------