Skip to content

Commit

Permalink
GO rewrite (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpetersen authored Mar 17, 2021
1 parent b67c5d4 commit 63cf7e6
Show file tree
Hide file tree
Showing 28 changed files with 2,327 additions and 803 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Global owners
* @jaredpetersen
4 changes: 1 addition & 3 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# These are supported funding model platforms

github: jaredpetersen
custom: https://paypal.me/jaredtpetersen
custom: ["https://cash.app/$jaredtpetersen", "https://paypal.me/jaredtpetersen"]
23 changes: 23 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Continuous Integration
on: pull_request
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up GO
uses: actions/setup-go@v2
with:
go-version: '1.16'
- name: Install dependencies
run: |
go install ./...
go get -u golang.org/x/lint/golint
- name: Build
run: env GOOS=linux GOARCH=arm GOARM=6 go build ./cmd/...
- name: Analyze code
run: |
golint ./...
go vet ./...
- name: Test
run: go test ./... -cover -timeout 1m
43 changes: 43 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Release
on:
push:
branches:
- master
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up GO
uses: actions/setup-go@v2
with:
go-version: '1.16'
- name: Install dependencies
run: |
go install ./...
go get -u golang.org/x/lint/golint
- name: Build
run: env GOOS=linux GOARCH=arm GOARM=6 go build ./cmd/...
- name: Analyze code
run: |
golint ./...
go vet ./...
- name: Test
run: go test ./... -cover -timeout 1m
- name: Get Changelog
id: changelog
uses: mindsers/changelog-reader-action@v2
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.changelog.outputs.version }}
name: ${{ steps.changelog.outputs.version }}
body: ${{ steps.changelog_reader.outputs.changes }}
draft: false
prerelease: false
files: |
raspilive
README.md
LICENSE
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6 changes: 1 addition & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
node_modules
*.log
camera
*.key
*.keyinfo
/raspilive
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2020-03-16
### Changed
- Rewrote application in GO
- Reset versioning to 1.0.0
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Jared Petersen
Copyright (c) 2021 Jared Petersen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
234 changes: 107 additions & 127 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,150 +1,130 @@
# raspi-live
[![NPM](https://img.shields.io/npm/v/raspi-live.svg)](https://www.npmjs.com/package/raspi-live)

raspi-live is a Node.js Express webserver that takes streaming video from the Raspberry Pi Camera module and makes it available on the web via [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) or [DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP).

Run it via a simple command line interface:
```
raspi-live start
```

The server will start serving the streaming files on `/camera`. Point streaming video players to `/camera/livestream.m3u8` for HLS or `/camera/livestream.mpd` for DASH.

# raspilive
📷 raspilive is a command-line application that streams video from the Raspberry Pi Camera module to the web

## Usage
```
$ raspi-live --help
Usage: raspi-live [options] [command]
raspilive streams video from the Raspberry Pi Camera Module to the web
self-contained raspberry pi video streaming server
For more information visit https://github.com/jaredpetersen/raspilive
Options:
-v, --version output the version number
-h, --help output usage information
Usage:
raspilive [command]
Commands:
start [options] start streaming video from the raspberry pi camera module
```
Available Commands:
hls Stream video using HLS
dash Stream video using DASH
help Help about any command
### Options
#### -v, --version
Output the version number.
Flags:
--debug enable debug logging
--fps int video framerate (default 30)
--height int video height (default 720)
-h, --help help for raspilive
--horizontal-flip horizontally flip video
-v, --version version for raspilive
--vertical-flip vertically flip video
--width int video width (default 1280)
#### -h, --help
Output information on how to use the command line interface.
Use "raspilive [command] --help" for more information about a command.
```

### Commands
#### start \[options\]
Start streaming video from the raspberry pi camera module.

##### Options
###### -d, --directory
The directory used to host the streaming video files. Those concerned about the long-term health of their pi's SD card may opt to point raspi-live to a RAMDisk so that the files are only stored in memory. However, this also means that you will be unable to recover any of the footage if the power is cut.

Defaults to `/home/<USERNAME>/camera` but `/srv/camera` is recommended as raspi-live is a server.

###### -f, --format
* [`hls`](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) (default)
* [`dash`](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP)

###### -w, --width
Video resolution width.

Defaults to `1280`.

###### -h, --height
Video resolution height.

Defaults to `720`.

###### -r, --framerate
Number of video frames per second.

Defaults to `25`.

###### -x, --horizontal-flip
Flip the video horizontally.

Disabled by default.

###### -y, --vertical-flip
Flip the video vertically.

Disabled by default.
#### HLS
The `hls` command muxes the video stream into the [HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming) video
streaming format and serves the produced content by starting a static file server.

###### -c, --compression-level
Level the video is compressed for download via the internet. Value must be between `0` and `9`.

Defaults to `9`.

###### -t, --time
The duration of the streaming video file in seconds.

Defaults to `2`.

###### -l, --list-size
The number of streaming video files included in the playlist.

Defaults to `10`.

###### -s, --storage-size
The number of streaming video files stored after they cycle out of the playlist. This is useful in cases where you want to look at previously recorded footage. The streaming video files are 2 seconds long by default so to have a 24-hour cycle of recorded video, specify `43200` (make sure to have enough storage space).

Defaults to `10`.

###### -p, --port
Port number the server runs on.

Defaults to `8080`.

###### -S, --secure
Specify to serve over HTTPS.

Disabled by default.

###### -C, --certificate
SSL certificate chain for the server.

###### -K, --key
SSL private key path for the certificate chain.
If you're not familiar with HLS, the technology works by splitting the video stream into small, consumable segments.
These segments are arranged into a constantly updating playlist of files. Clients periodically read these playlists,
download the listed videos, and queue up the segments to produce a seamless playback experience.
[Twitch uses it](https://blog.twitch.tv/en/2015/12/18/twitch-engineering-an-introduction-and-overview-a23917b71a25/)
to distribute streaming video to all of its viewers.

```
Stream video using HLS
Usage:
raspilive hls [flags]
Flags:
--port int static file server port
--directory string static file server directory
--tls-cert string static file server TLS certificate
--tls-key string static file server TLS key
--segment-type string format of the video segments (valid ["mpegts", "fmp4"], default "mpegts")
--segment-time int target segment duration in seconds (default 2)
--playlist-size int maximum number of playlist entries (default 10)
--storage-size int maximum number of unreferenced segments to keep on disk before removal (default 1)
-h, --help help for hls
Global Flags:
--debug enable debug logging
--fps int video framerate (default 30)
--height int video height (default 720)
--horizontal-flip horizontally flip video
--vertical-flip vertically flip video
--width int video width (default 1280)
```

## Install
### Raspberry Pi Camera module
raspi-live only supports streaming video from the Raspberry Pi camera module. Here's a the official documentation on how to connect and configure it: https://www.raspberrypi.org/documentation/usage/camera/.
#### DASH
The `dash` command muxes the video stream into the
[DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) video streaming format and serves the
produced content by starting a static file server.

### FFmpeg
raspi-live uses FFmpeg, a video conversion command-line utility, to process the streaming H.264 video that the Raspberry Pi camera module outputs. Version 4.0 or higher is required. Here's how to install it on your Raspberry Pi:
DASH effectively utilizes the same mechanism for streaming video as HLS. The video is split into small segments and
listed in a changing playlist file. Clients download the playlist and the videos listed in it to piece the video
together seamlessly.

1. Download and configure FFmpeg via:
```
sudo apt-get install libomxil-bellagio-dev
wget -O ffmpeg.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot-git.tar.bz2
tar xvjf ffmpeg.tar.bz2
cd ffmpeg
sudo ./configure --arch=arm --target-os=linux --enable-gpl --enable-omx --enable-omx-rpi --enable-nonfree --extra-ldflags="-latomic"
Stream video using DASH
Usage:
raspilive dash [flags]
Flags:
--port int static file server port
--directory string static file server directory
--tls-cert string static file server TLS certificate
--tls-key string static file server TLS key
--segment-time int target segment duration in seconds (default 2)
--playlist-size int maximum number of playlist entries (default 10)
--storage-size int maximum number of unreferenced segments to keep on disk before removal (default 1)
-h, --help help for dash
Global Flags:
--debug enable debug logging
--fps int video framerate (default 30)
--height int video height (default 720)
--horizontal-flip horizontally flip video
--vertical-flip vertically flip video
--width int video width (default 1280)
```
2. Run `sudo make -j$(grep -c ^processor /proc/cpuinfo)` to build FFmpeg and get a cup of coffee or two. This will take a while.
3. Install FFmpeg via `sudo make install` regardless of the model of your Raspberry Pi.
4. Delete the FFmpeg directory and tar file that were created during the download process in Step 1. FFmpeg has been installed so they are no longer needed.

### CLI
Install it globally:
```
npm install raspi-live -g
raspi-live --help
```
Or use npx:
```
npx raspi-live --help
```
### Performance Tips
#### HLS & DASH
HLS and DASH are inherently latent streaming technologies. However, you can still produce some lower latency video
streams.

The general recommendations seem to be:
- Reduce the segment size
- Increase the number of segments in the playlist to build up a buffer

## Video Stream Playback
raspi-live is only concerned with streaming video from the camera module and does not offer a playback solution.
Experiment with the flags and see what seems to work best for your Pi. We try to provide "sane" defaults but Raspberry
Pis are computationally diverse so you may find better performance with some tweaking.

Browser support between the different streaming formats varies so in most cases a JavaScript playback library will be necessary. For more information on this, check out [Mozilla's article on the subject](https://developer.mozilla.org/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/Live_streaming_web_audio_and_video).
Additionally, you may find that the SD card on the Raspberry Pi is a limitation. Fast disk read/writes are important
and SD cards can only perform so many in their lifetime. For better performance and longevity, you may consider setting
up a [RAM drive](https://en.wikipedia.org/wiki/RAM_drive) so that the files are stored in memory instead.

## Installation
raspilive uses [raspivid](https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspivid.md) to operate the
Raspberry Pi Camera Module. This is already available on the Raspbian operating system and can be enabled via
[raspi-config](https://www.raspberrypi.org/documentation/configuration/raspi-config.md).

raspilive also uses [Ffmpeg](https://ffmpeg.org/), a prominent video conversion command line utility, to process the
streaming video that the Raspberry Pi Camera Module outputs. Version 4.0 or higher is required.
```zsh
sudo apt-get install ffmpeg
```

## Performance
HLS and DASH inherently have latency baked into the technology. To reduce this, set the `time` option to 1 or .5 seconds and increase the list and storage size via the `list-size` and `storage-size` options. Ideally, there should be 12 seconds of video in the list and 50 seconds of video in storage.
Download the latest version of raspilive from the [Releases page](https://github.com/jaredpetersen/raspilive/releases).
All of the release binaries are compiled for ARM 6 and are compatible with Raspberry Pi.
Loading

0 comments on commit 63cf7e6

Please sign in to comment.