GithubHelp home page GithubHelp logo

leandromoreira / resty-bakery Goto Github PK

View Code? Open in Web Editor NEW
21.0 5.0 3.0 14.36 MB

An Nginx+Lua library to modify media manifests like HLS and MPEG Dash, acting like a proxy.

Home Page: https://github.com/leandromoreira/resty-bakery

License: BSD 3-Clause "New" or "Revised" License

Lua 97.58% Makefile 0.85% Dockerfile 1.57%
lua hls mpeg-dash nginx resty manipulator proxy filtering modify

resty-bakery's Introduction

Build Status license

Resty-Bakery [WIP]

It's a Nginx+Lua library, strongly inspired by the CBS Bakery, to modify media manifests on-the-fly, like HLS and MPEG Dash. It acts as a proxy between (or in) the frontend and your origin.

This is very useful due to the fact that some devices can't play with a higher bitrate, multiple codecs, multiple frame rate, and so on.

Getting started

# run the nginx
docker run --rm -it -p 8080:8080 leandromoreira/resty-bakery

# fetch unfiltered manifest
curl "http://localhost:8080/media/generic_master.m3u8"

# fetch renditions (variants) with bandwidth >= 800000 and with frame rate = 60 or 60/1
curl "http://localhost:8080/media/b(800000)fps(60,60:1)/generic_master.m3u8"

Filters

  • Bandwidth (/path/to/media/f/b(min,max)/manifes.m3u8) - filters based on uri path following the format b(min bandwidth, max bandwidth).
  • Framerate (/path/to/media/f/fps(30,30000:1001)/manifes.m3u8) - filters out based on uri path following the format b(list of frame rates).

Nginx usage example

# Let's suppose our origin hosts media at /media/<manifest>.<extension>
# So what we need to do is to set up a location to act like a proxy
# Also, let's say we're going to use /media/<filters>/<manifest>.<extension> to pass the filters
#  ex: /media/b(1500000)/playlist.m3u8
    location /media {
        proxy_pass http://origin;

        # we need to keep the original uri with its state, since we're going to rewrite
        # from /media/<filters>/<manifest>.<extension> to /media/<manifest>.<extension>
        set_by_lua_block $original_uri { return ngx.var.uri }

        # when the Lua code may change the length of the response body,
        # then it is required to always clear out the Content-Length
        header_filter_by_lua_block { ngx.header.content_length = nil }

        # rewriting to the proper origin uri, effectively removing the filters
        rewrite_by_lua_block {
          local uri = ngx.re.sub(ngx.var.uri, "^/media/(.*)/(.*)$", "/media/$2")
          ngx.req.set_uri(uri)
        }

        # applying the filters (after the proxy/upstream has replied)
        # this is where the magic happens
        body_filter_by_lua_block {
          local modified_manifest = bakery.filter(ngx.var.original_uri, ngx.arg[1])
          ngx.arg[1] = modified_manifest
          ngx.arg[2] = true
        }
    }

Test locally

make run

# open another tab

# unmodified manifest
curl -v "http://localhost:8080/media/ffmpeg_master.m3u8"
curl -v "http://localhost:8080/media/ffmpeg_dash.mpd"

# filters out renditions with bandwidth < 1500000
curl -v "http://localhost:8080/media/b(1500000)/ffmpeg_master.m3u8"
curl -v "http://localhost:8080/media/b(1500000)/ffmpeg_dash.mpd"

# filters out renditions with bandwidth > 1500000
curl -v "http://localhost:8080/media/b(0,1500000)/ffmpeg_master.m3u8"
curl -v "http://localhost:8080/media/b(0,1500000)/ffmpeg_dash.mpd"

# filters bandwidth > 800000 and excludes frame rate 60
curl "http://localhost:8080/media/b(800000)fps(60)/generic_master.m3u8"
curl "http://localhost:8080/media/b(800000)fps(60,60:1)/generic_dash.mpd"


# PS: there is an mmedia location just to provide manifests without
# data transfer them in chunked encoding mechanism
# this example was done due some CTV that can't handle chunked transfer encoding

Tests

make test

Lint

make lint

resty-bakery's People

Contributors

leandromoreira avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

resty-bakery's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.