Giter Club home page Giter Club logo

rotisserie's Introduction

rotisserie

Build Status License

Read this in other languages: **.

LIVE NOW

rotisserie takes the concept of the red zone in American football and applies it to the popular online battle royale game PLAYERUNKNOWN'S BATTLEGROUNDS. The idea is to always be viewing the most popular PUBG twitch stream with the least amount of people alive in-game.

Included Component

Featured Technologies

Prerequisite

The following pieces of software are required to run rotisserie locally:

You can install these dependencies with one of the two following commands, depending on your os:

  • Ubuntu:
  $ sudo apt-get install tesseract-ocr ffmpeg imagemagick
  $ pip install livestreamer
  • macOS:
  $ brew install tesseract ffmpeg imagemagick
  $ pip install livestreamer

Create a Kubernetes cluster with either Minikube for local testing, or with IBM Bluemix Container Service to deploy in cloud. The code here is regularly tested against Kubernetes Cluster from Bluemix Container Service using Travis.

Steps

  1. Get an OAuth Token for livestreamer
  2. Setting up Environment Variables
  3. Build the images
  4. Deploy locally
  5. Deploy using Docker
  6. Deploy using Kubernetes

1. Getting an OAuth Token for Twitch

  1. On a machine with a browser installed, run the following:
  $ livestreamer --twitch-oauth-authenticate
  1. A browser window will open, and prompt you to authorize livestreamer to use your twitch account. Click Authorize.

  2. Your browser will refresh, and a page saying "SORRY, this page does not exist yet" will appear. Ignore this. In your address bar, there will be a callback URL with access_token=<TOKEN>. This is your OAuth token, copy it down and proceed to the next section.

2. Setting up Environment Variables

  • Create an environment variable for your docker username.
  $ export docker_username="YOUR_DOCKER_USERNAME"
  • Create an enviornment variable for your token you retrieved in the previous step.
  $ export token="YOUR_OAUTH_TOKEN"
  • Create an environment variable for your clientID.

You must create an app in your Twitch account using the developer mode (https://dev.twitch.tv/) to retrieve the clientID

  $ export clientID="YOUR_CLIENT_ID"
  • Create an environment variable for the ROTISSERIE_OCR_SERVICE_HOST and ROTISSERIE_OCR_SERVICE_PORT. This can be set to localhost and 3001 if running locally, or the IP address and port of a remote OCR host if running in containers. Mimic the environment variables exported by kubernetes.
  $ export ROTISSERIE_OCR_SERVICE_HOST="localhost"
  $ export ROTISSERIE_OCR_SERVICE_PORT="3001"

3. Build the Images

  • Clone the repo.
 $ git clone https://github.com/IBM/rotisserie.git
 $ cd rotisserie
  • Build and Push the Docker Image. You would need to push it if you want to deploy the application in Kubernetes.
$ docker build -t $docker_username/rotisserie-ocr -f deploy/images/ocr.Dockerfile .
$ docker build -t $docker_username/rotisserie-app -f deploy/images/app.Dockerfile .
$ docker push $docker_username/rotisserie-ocr
$ docker push $docker_username/rotisserie-app

4. Running It Locally

  • Install with npm.
  $ npm install .
  • Navigate to the rotisserie dir if you aren't there already, and start the app:
  $ node ocr.js 2>&1 >/dev/null &
  $ node app.js

Now you can open a browser and navigate to http://localhost:3000 to watch rotisserie.

5. Running in a Container

You can also run rotisserie in a docker container.

  • Start up the containers:
  $ docker run -d -p 3001:3001 --name rotisserie-ocr $docker_username/rotisserie-ocr
  $ docker run -d -p 3000:3000 --name rotisserie-app -e ROTISSERIE_OCR_SERVICE_HOST=$ROTISSERIE_OCR_SERVICE_HOST -e ROTISSERIE_OCR_SERVICE_PORT=$ROTISSERIE_OCR_SERVICE_PORT -e token=$token -e clientID=$clientID $docker_username/rotisserie-app

Now you can open a browser and navigate to http://localhost:3000 to watch rotisserie.

6. Running in Kubernetes

note: Ensure your $OCR_HOST environment variable is set to the cluster_public_ip:3001.

  1. Create a Kubernetes Secret for your OAuth token. You will need to encode the data you want in Base64 for the Kubernetes Secret.
$ echo -n "YOUR_OAUTH_TOKEN" | base64
  1. Modify the rotisserie-secrets.yaml file to use your token
...
data:
  token: YOUR_OAUTH_TOKEN_IN_BASE64
  1. Finally, create the Kubernetes Secret.
$ kubectl create -f rotisserie-secrets.yaml
  1. Modify the rotisserie-app.yaml and rotisserie-ocr.yaml yaml files to use your image.
...
    containers:
    - name: rotisserie-app
      image: <docker_username>/rotisserie-app
  1. Deploy the OCR service then the main application.
$ kubectl apply -f rotisserie-ocr.yaml
$ kubectl apply -f rotisserie-app.yaml
  • To access your application. You would need the public IP address of your cluster. If you don't have a load balancer, you can use the Node Port.
# For clusters provisioned with Bluemix
$ bx cs workers YOUR_CLUSTER_NAME

# For Minikube
$ minikube ip
  • Now you can go to http://IP_ADDRESS:30080

Production Detail

The production version of rotisserie has slightly different operational procedures. The production kubernetes manifest is located in the deploy directory. It is typically interacted with via the provided Makefile. Major differences between the production rotisserie and the one used in the developer journey are use of ingress controllers in kuberenetes and adding Letsencrypt.

There are a few commands we can use to work with the deployment.

To deploy without letsencrypt use make roll

make roll

To deploy with letsencrypt use make full-roll

make full-roll

To redeploy the deployments, without removing svc/ing/other, use make redeploy

make redeploy

To delete the entire deployment we can use make purge

make purge

Note: this depends on you deploying with a unique sha. See the 'make-rev' rule in the Makefile. In most cases git pull; make roll should work. In cases where a roll failed or the app failed for reasons not connected to the code, a dummy commit might need to be added before re-rolling. Please only roll from master.

Allowing and blocking streamers

To allowlist simply set an environment variable called ROTISSERIE_ALLOWLIST to a string with space separated usernames. Same with blocklisting, but with the environment variable ROTISSERIE_BLOCKLIST.

License

This code pattern is licensed under the Apache Software License, Version 2. Separate third party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.

Apache Software License (ASL) FAQ

rotisserie's People

Contributors

anthonyamanse avatar dolph avatar greghaynes avatar imgbotapp avatar kant avatar ljbennett62 avatar mpetason avatar nibalizer avatar pwplusnick avatar rmoe avatar stevemar avatar wwalisa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rotisserie's Issues

OCR service with AWS Rekognition

I was experimenting with an idea about doing OCR on snapshots of twitch streams of speed runners, and reporting statistics or perhaps even pushing notifications when a speed runner is close to a world record or personal best run. In my research, I came across rotisserie, which at a high level seemed to be very similar to what I was trying to do.

Rather than running and managing your own tesseract instance, have you thought about making use of some out of the box "OCR As a Service" solutions? I don't know how much it typically costs to run the OCR service currently, but I think it's quite possible that the cost could be reduced by utilizing something like AWS Rekognition: https://aws.amazon.com/rekognition/ (you can do text detection on the first 5k images per month free, 1$ per 1000 images after that - no cost of provisioning servers or containers)

I think it would be nice to never have to think about running tesseract or training models - and you could also have an API gateway route to a Lambda function to be responsible for calling AWS Rekognition.

Microsoft has a similar offering as well, which might also be a good solution: https://azure.microsoft.com/en-us/services/cognitive-services/computer-vision/

Any thoughts on an approach that avoids running or managing the actual OCR "stuff"?

Remove links to rotisserie.tv

IBM no longer owns the domain name, and should remove it from all links. It is now owned by an organization promoting esports gambling, and probably not one IBM wishes to be associated with.

http should redirect to https for `dev.rotisserie.tv`

http://dev.rotisserie.tv is the default nginx landing page.

the Thanks slide at https://blog.eggshell.me/rotisserie-talk/#39
links to dev.rotisserie.tv which by default is interpreted as http when you copy and paste it in.
http://dev.rotisserie.tv

It should be a direct clicky link to https://dev.rotisserie.tv

Additionally http://dev.rotisserie.tv should redirect to https://dev.rotisserie.tv.

  • fix slides with direct link to https://dev.rotisserie.tv
  • make http://dev.rotisserie.tv redirect to https://dev.rotisserie.tv

ffmpeg related crash

Not sure what went down here.

taking screenshot of stream: Itallas
events.js:182
      throw er; // Unhandled 'error' event
      ^

Error: ffprobe exited with code 1
ffprobe version 2.8.11-0ubuntu0.16.04.1 Copyright (c) 2007-2017 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
  WARNING: library configuration mismatch
  avcodec     configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv --enable-version3 --disable-doc --disable-programs --disable-avdevice --disable-avfilter --disable-avformat --disable-avresample --disable-postproc --disable-swscale --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libvo_aacenc --enable-libvo_amrwbenc
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1cdfc80] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1cdfc80] moov atom not found
./streams/clips/DrLupo.mp4: Invalid data found when processing input

    at ChildProcess.<anonymous> (/home/nibz/projects/pubg/pubgredzone/node_modules/fluent-ffmpeg/lib/ffprobe.js:233:22)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12)

Port functionality to node.js

The following functionality / control flow should be ported from bash to node.js:

- [ ] dependency checking
- [ ] directory checks
- [ ] environment variable checks

  • getting a list of english language streams from twitch
  • recording a clip (preferably just a frame) of each stream from the list grabbed in the previous step.
  • getting a thumbnail (single frame) out of the clip recorded above IFAF just getting a single frame is not possible.
  • cropping of thumbnails to just be the box containing the number of alive players.
  • usage of tesseract to grok out the numbers from the cropped pictures.
  • placing names of streams along with their number alive into an array, sorting it, and getting the name of the best (lowest # of alive players) channel.
  • comparing the newest "best" stream to the previously-determined best stream (AKA the one that is currently broadcasting on the site), seeing which one has a lower number and choosing the best one from there.
  • writing the channel name to public/index.html.

Depends-On: #1

Logging

It might be nice to report some of the logic (which streams were polled, their "alive" numbers, which one was picked, etc) and of course errors to a log.

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.