anonstream/README.md

134 行
6.8 KiB
Markdown
Raw 通常表示 履歴

2021-04-10 02:10:22 +09:00
# onion-livestreaming
2021-04-10 03:24:40 +09:00
Recipe for livestreaming over the Tor network
2021-04-10 15:55:16 +09:00
![Screenshot of the livestream web interface](demo.png)
2021-05-14 16:17:18 +09:00
This was originally made for fun over the course of five days and hence sloppiness may pervade.
* [Repo on GitHub](https://github.com/ninya9k/onion-livestreaming)
* [Repo on GitLab](https://gitlab.com/ninya9k/onion-livestreaming)
2021-04-10 03:24:40 +09:00
2021-05-14 16:29:11 +09:00
This works on Linux, and should work on macOS and Windows with some tweaking. Look at the [setup tutorial](#tutorial).
2021-04-10 03:24:40 +09:00
## Dependencies
2021-04-10 03:46:23 +09:00
* Tor
* FFmpeg
2021-04-10 03:24:40 +09:00
* [Flask](https://github.com/pallets/flask)
2021-04-10 03:45:29 +09:00
* [captcha](https://github.com/lepture/captcha)
2021-04-10 03:24:40 +09:00
* [Flask-HTTPAuth](https://github.com/miguelgrinberg/Flask-HTTPAuth) (to identify the broadcaster in chat)
* [Flask-Compress](https://github.com/colour-science/flask-compress) (should probably be optional)
2021-04-10 03:33:56 +09:00
* Knowledge of FFmpeg and Tor
2021-04-10 03:24:40 +09:00
## Features
2021-04-10 15:15:30 +09:00
* Twitch-looking web interface (mobile friendly)
2021-04-10 03:24:40 +09:00
* Change stream title as you're streaming
* Viewer count
* Stream on/off indicator and playback error messages with prompts to refresh
2021-04-10 03:24:40 +09:00
* Chat with custom names & tripcodes
* Ban/unban chatters & hide messages
2021-04-10 03:45:29 +09:00
* Flood detection / liberal captcha
2021-04-12 00:19:39 +09:00
* Shows stream uptime
* List of users watching / not watching
2021-05-15 13:35:48 +09:00
* Optionally uses videojs (append `?videojs=1` to the URL to enable it)
* With videojs disabled, you can scrub backwards and forwards on the video timeline. If you scrub to the end (the most recent segment), you can achieve really quite low latency, as low as 10 seconds.
2021-04-10 23:55:37 +09:00
* Works without JavaScript
2021-04-10 03:24:40 +09:00
## Issues
* CSS is spaghetti (e.g. the PureCSS framework is used sometimes when it might not need be)
* AFAIK the FFmpeg command in `stream.sh` only works on Linux, change it for other OSs
2021-05-15 22:40:17 +09:00
* Slow: stream delay of at least 10 seconds (>30 seconds with videojs enabled). Hopefully this will decrease when congestion control gets into Tor: https://youtu.be/watch?v=zQDbfHSjbnI. ([This article](https://www.martin-riedl.de/2020/04/17/using-ffmpeg-as-a-hls-streaming-server-part-8-reducing-delay/) explains what causes HLS to have latency.)
* Doesn't use low-latency HLS
2021-04-10 03:24:40 +09:00
## How it works
* FFmpeg creates an HLS stream
* Flask creates a website interface for the stream
2021-04-10 03:24:40 +09:00
* tor makes the website accessible at an onion address
2021-04-10 03:31:27 +09:00
## Explanation of the FFmpeg command in `stream.sh`
2021-04-10 03:24:40 +09:00
2021-04-21 00:53:44 +09:00
The FFmpeg command in `stream.sh` was based on [this series of articles by Martin Riedl](https://www.martin-riedl.de/2020/04/17/using-ffmpeg-as-a-hls-streaming-server-overview/).
2021-05-15 22:44:16 +09:00
### video input (differs between OSs)
2021-05-15 22:40:17 +09:00
`-thread_queue_size 2048 -video_size "$BOX_WIDTH"x"$BOX_HEIGHT" -framerate $FRAMERATE -f x11grab -i :0.0+$BOX_OFFSET_X,$BOX_OFFSET_Y`
* `-thread_queue_size 2048` prevents ffmpeg from giving some warnings
* `-video_size "$BOX_WIDTH"x"$BOX_HEIGHT"` sets the size of the video
* `-framerate $FRAMERATE` sets the framerate of the video
* `-f x11grab` tells ffmpeg to use the `x11grab` device, used for recording the screen on Linux
* `-i :0.0+$BOX_OFFSET_X,$BOX_OFFSET_Y` sets the x- and y-offset for the screen recording
2021-05-15 22:44:16 +09:00
### audio input (differs between OSs)
2021-05-15 22:40:17 +09:00
`-thread_queue_size 2048 -f pulse -i default`
2021-05-15 22:44:16 +09:00
### video encoding
2021-05-15 22:40:17 +09:00
`-c:v libx264 -b:v "$VIDEO_BITRATE"k -tune zerolatency -preset slower -g $FRAMERATE -sc_threshold 0 -pix_fmt yuv420p`
2021-05-19 09:36:53 +09:00
### video filters
2021-05-15 22:40:17 +09:00
`-filter:v scale=$VIDEO_WIDTH:$VIDEO_HEIGHT,"drawtext=fontfile=/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf:text='%{gmtime}':fontcolor=white@0.75:box=1:boxborderw=2:boxcolor=black@0.5:fontsize=24:x=8:y=6"`
2021-05-19 09:36:53 +09:00
* `scale=$VIDEO_WIDTH:$VIDEO_HEIGHT` scales the video to the desired size
* `drawtext...` draws the date and time in the top left
2021-05-15 22:44:16 +09:00
* you might need to change the font `/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf` if you're on macOS and definitely if you're on Windows
2021-05-15 22:40:17 +09:00
2021-05-15 22:44:16 +09:00
### audio encoding
2021-05-15 22:40:17 +09:00
`-c:a aac -b:a "$AUDIO_BITRATE"k -ac $AUDIO_CHANNELS`
2021-05-15 22:44:16 +09:00
### HLS configuration
2021-05-15 22:40:17 +09:00
`-f hls -hls_init_time 0 -hls_time $HLS_TIME -hls_list_size $HLS_LIST_SIZE -hls_flags delete_segments -hls_segment_type fmp4`
2021-05-15 22:44:16 +09:00
### strip all metadata
2021-05-15 22:40:17 +09:00
`-map_metadata -1 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact`
2021-05-15 22:44:16 +09:00
### output
2021-05-15 22:40:17 +09:00
`stream/stream.m3u8`
2021-04-10 03:31:27 +09:00
2021-04-10 03:24:40 +09:00
## Tutorial
To run this yourself, get this source code. As the project currently exists you might need to change some things:
2021-04-21 00:57:30 +09:00
`stream.sh` as it exists in this repo is set up to record your screen and system audio on Linux. See https://trac.ffmpeg.org/wiki/Capture/Desktop for the syntax for different OSs.
2021-04-21 00:53:44 +09:00
2021-04-13 22:23:11 +09:00
* If you're on Windows `stream.sh` will be wrong for you and so will all the fonts in `config.json`. `stream.sh` uses `$$` to get its process ID, you'll have to use the Windows equivalent.
* If you're on macOS `stream.sh` might need to be changed a bit and you might not have the fonts in `config.json`.
* If you're on Linux `stream.sh` will probably be alright but you might not have all the fonts in `config.json`.
2021-04-10 03:24:40 +09:00
2021-04-21 01:09:19 +09:00
As an aside: you can change the command in stream.sh to record anything you want, it doesn't have to be just your screen and system audio. If you want to change stuff around, just know that all that's required is: (1) `stream/pid.txt` contains `stream.sh`'s process ID, (2) `stream/start.txt` contains the time the stream started, (3) HLS segments appear as `stream/stream*.m4s`, (4) `stream/init.mp4` is the inital HLS segment, and (5) `stream/stream.m3u8` is the HLS playlist. (All this is taken care of in `stream.sh` by default.)
2021-04-21 01:07:31 +09:00
Assuming your FFmpeg command is working, this is what you have to do.
2021-04-10 03:24:40 +09:00
### Start streaming
2021-04-10 03:24:40 +09:00
#### FFmpeg
2021-04-10 03:24:40 +09:00
Go to the project root and type `sh stream.sh`. This starts the livestream.
2021-04-10 03:24:40 +09:00
#### Flask
2021-04-10 03:24:40 +09:00
Go to the project root and type `flask run`. This starts the websever.
#### tor
2021-04-10 03:24:40 +09:00
Now your webserver is running on port 5000 (or whichever port you set it to, if you did that). We need to tell tor to create a hidden service and to point it at port 5000.
In your [torrc](https://support.torproject.org/tbb/tbb-editing-torrc/), add these two lines
```
HiddenServiceDir $PROJECT_ROOT/hidden_service
HiddenServicePort 80 127.0.0.1:5000
```
2021-04-12 00:41:42 +09:00
where `$PROJECT_ROOT` is the root folder of this project. When you reload tor it will create the `hidden_service` directory and your website will be online. Your onion address is in `hidden_service/hostname`. You only need to do this once.
### While streaming
2021-04-12 00:41:42 +09:00
To appear as the broadcaster in chat, go to `/broadcaster` and log in with the username `broadcaster` and the password printed in your terminal when you started Flask.
2021-04-12 00:38:10 +09:00
You can change the stream title while streaming and it will update for all viewers. Edit `title.txt` to do that.
2021-04-16 21:50:43 +09:00
If you restart FFmpeg while you're streaming, viewers will have to refresh the page. All viewers are prompted to refresh the page.
### Stop streaming
2021-04-24 11:18:38 +09:00
To stop streaming, stop FFmpeg. You can delete the files in `stream/` if you want. To start streaming again just rerun `stream.sh`.
2021-04-12 00:38:10 +09:00
If you restart Flask, the chat will be cleared, you'll have to log in again, and everyone else will have to do the captcha again.