Skip to content

AhmedAbouelkher/c-hls-dash-video-processor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C HLS/DASH Video Processor

A small C CLI that transcodes a source video into adaptive bitrate streaming outputs. It uses ffprobe to read metadata, ffmpeg to transcode and extract assets, and gpac to package the final HLS or HLS + DASH outputs.

Gemini_Generated_Image_ngjtvdngjtvdngjt

What it does

The tool takes one input video and produces:

  • Resolution-specific MP4 variants
  • No-audio variants for packaging
  • An AAC audio track when the source has audio
  • An HLS playlist, or combined HLS + DASH playlists
  • A thumbnail image

It skips any resolution that is higher than the source video, so it does not upscale beyond the input. Logs are written to stderr with timestamps and levels.

TODOs

I am happy to get any help or contributions to the project.

  • Implement the basic functionality by calling ffmpeg (processing) and gpac (packaging) commands.
  • Extend the functionality to support gpac filters for more advanced processing.
  • Remove the usage of ffprobe and gpac commands in favor of using the libraries directly (libgpac, libavformat, libavcodec, and libavutil).
  • Add more practical test cases for the tool to ensure it works as expected.
    • Make sure that the tool can handle large files (10GB+) and long videos (10 hours+).
    • Make sure that the tool can handle different video formats (H.264, H.265, VP9, AV1, etc.), Currently it only supports H.264.
    • Make sure that the tool handle internal errors correctly specially when calling libraries directly.
  • Add more CLI options for more advanced processing (thumbnail generation, audio extraction, etc.).
  • Package the tool as a Docker image.
  • Package the tool as a static binary for Linux. (this might be not possible at the moment).

Requirements

Install these tools and make sure they are available in PATH:

  • ffmpeg
  • gpac

The project can be built against either ffmpeg.c or gpac.c through the IMPL variable in the Makefile.

On Windows, you can follow the instructions for installing gpac and ffmpeg from their official websites.

On macOS, a typical setup is:

brew install ffmpeg gpac

On Ubuntu, a typical setup is:

sudo apt-get install ffmpeg gpac

Warning: The version of gpac in the default Ubuntu repository is too old. You need to install the latest version from the PPA.

Build

To build the tool:

make build

IMPL options are available:

  • IMPL=libgpac: Build with the libgpac-backed implementation. (Default, Recommended)
  • IMPL=ffmpeg: Build with the ffmpeg-backed implementation.
  • IMPL=gpac: Build with the gpac-backed implementation.

Test

Run the unit test binary with:

make test

This compiles the test binary and runs a few focused checks for CLI helpers and resolution parsing.

Usage

./video-processor <source_video> [options]

Options

  • -d <path>: output directory
  • -t <type>: packaging type, either hls or hls_and_dash
  • -r <list>: comma-separated resolution list
  • -f: force overwrite of an existing output directory

Defaults

  • If -d is omitted, the output directory is derived from the input file name.
  • If -t is omitted, the output type defaults to hls.
  • If -r is omitted, all supported resolutions are enabled:
    • 240p
    • 360p
    • 480p
    • 720p
    • 1080p
  • If the output directory already exists, the command fails unless -f is used.

Examples

Process a video with the default settings:

./video-processor sample.mp4

Write outputs to a custom directory:

./video-processor sample.mp4 -d output/stream

Generate only selected resolutions:

./video-processor sample.mp4 -r 480p,720p,1080p

Generate both HLS and DASH outputs:

./video-processor sample.mp4 -t hls_and_dash

Force overwrite an existing output directory:

./video-processor sample.mp4 -f -d output/stream

Output Layout

For an input named sample.mp4, the output directory will contain artifacts like:

sample/
├── play_240p.mp4
├── play_360p.mp4
├── play_audio.aac
├── playlist.m3u8
├── thumbnail.jpg
├── video_240p/
└── video_360p/

If -t hls_and_dash is used, the main playlist becomes playlist.mpd.

Temporary *_noaudio.mp4 files are removed after packaging. When -f is provided, an existing output directory is removed before processing starts.

Playing The Stream

You can open playlist.m3u8 in either mpv or VLC:

mpv sample/playlist.m3u8

In VLC, use "Open Network Stream" or open the file directly and point it to sample/playlist.m3u8.

Resolution Presets

Supported resolution IDs are:

  • 240p
  • 360p
  • 480p
  • 720p
  • 1080p

Each preset has its own width, height, CRF, bitrate, maxrate, and buffer settings in src/resolutions.c.

Implementation Notes

  • The CLI keeps the first argument as the input video path.
  • If the output directory already exists, the program exits unless -f is provided.
  • Resolutions higher than the source height are skipped.
  • Audio is extracted only when the source contains an audio stream, and mkv inputs are handled by re-encoding to AAC.
  • Logging uses a small stderr logger with INFO, DEBUG, WARN, ERROR, and FATAL levels.
  • Packaging is done with external tools instead of native libraries, which keeps the C code small and easy to follow.

License

MIT

About

A small C CLI that transcodes a source video into adaptive bitrate streaming outputs. It uses ffprobe to read metadata, ffmpeg to transcode and extract assets, and gpac to package the final HLS or HLS + DASH outputs.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors