Skip to content

Commit

Permalink
Merge pull request #14 from TUS-OSK/hls-from-rtmp
Browse files Browse the repository at this point in the history
HLS with RTMP
  • Loading branch information
ilim0t authored Jul 21, 2019
2 parents b050001 + 3139927 commit 8ae420f
Show file tree
Hide file tree
Showing 12 changed files with 327 additions and 181 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,5 @@ typings/
.envrc
*.png
*.jpeg
*.jpg
*.jpg
hls/
73 changes: 23 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
OSK の部室の様子を様子をオンラインで確認できるプロジェクト 部室ちゃん
その部室に置いてある PC 側で動かすプログラム

## Support

以下の OS をサポートします

- Ubuntu 18.04
- macOS 10.14

## Setup

### ngrok
Expand Down Expand Up @@ -41,8 +48,14 @@ ngrok で得られる URL はは変動するので,[API Gateway](https://aws.a
│ └─ GET
├─ /login
│ └─ GET
├─ /logout
│ └─ GET
├─ /oauth-redirect
│ └─ GET
├─ /photo.jpeg
│ └─ GET
├─ /photo-viewer
│ └─ GET
├─ /stream
│ ├─ GET
│ └ /{file+}
Expand Down Expand Up @@ -85,7 +98,7 @@ export AWS_REST_API_ID="h7c..."
export SLACK_CLIENT_ID="179..."
export SLACK_CLIENT_SECRET="38b..."
export LIVE_PRIVATE_KEY="presetprivatekey"
export PRIVATE_KEY="presetprivatekey"
export WORKSTATION_ID="VOW38CP2D"
```
Expand All @@ -108,60 +121,22 @@ brew install ffmpeg
sudo apt-get install ffmpeg
```

## Run

```bash=
npm start
```
### RAM Disk

### Streaming

Linux の場合は自動で行われますが,それ以外のときエラーが発生します。
その時の手動実行方法を書き置きます。

rtmp に向けストリーミングします。
OBS などでも行えますがここでは ffmpeg の例を書きます。

**Use Video files**

```bash=
ffmpeg -re -i example.mp4 -c copy -f flv rtmp://localhost/live/stream
```

**Use USB Camera on Ubuntu**
Ubuntu では自動で行われますが,Mac の場合 OS 起動の度に手動で行う必要があります。
以下のように実行してください。

```bash=
ffmpeg \
-framerate 5 \
-video_size 960x720 \
-i /dev/video0 \
-vcodec libx264 \
-preset veryfast \
-tune zerolatency \
-b 8M \
-vf "drawtext=fontfile=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: \
text='%{localtime\:%T}': [email protected]: x=7: y=700" \
-hls_flags delete_segments \
-g 20 \
-f hls [Directory of ramdisk]/output.m3u8
hdiutil attach -nomount ram://204800
newfs_hfs /dev/disk2
mkdir -p /path/to/bushitsuchan-PC/hls
mount -t hfs /dev/disk2 /path/to/bushitsuchan-PC/hls
```

**Use USB Camera on macOS**
## Run

```bash=
ffmpeg \
-f avfoundation \
-framerate 30 \
-re -i 0 \
-r 5 \
-vcodec libx264 \
-preset veryfast \
-tune zerolatency \
-vf "drawtext=fontfile=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf: \
text='%{localtime\:%T}': [email protected]: x=7: y=700" \
-hls_flags delete_segments \
-g 20 \
-f hls [Directory of ramdisk]/output.m3u8
npm start
```

## Usage
Expand All @@ -184,5 +159,3 @@ Remote URL: https://[AWS_REST_API_ID].execute-api.[REGION].amazonaws.com/prod
すると,初回実行時(過去に Slack で認証をしていなければ) Slack の認証ページへリダイレクトされます。
Sign in すると自動的に配信再生ページへ移動します。

> 再生が開始されないことがあるので,静止画で止まったままのときはサイトをリロードしてください。
64 changes: 55 additions & 9 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,77 @@
const RtmpServer = require('./rtmp-server');
const ngrok = require('./ngrok');
const Server = require('./server');
const aws = require('./aws');
const Stream = require('./stream');
const { daemon } = require('./utils');

const config = {
restApiId: process.env.AWS_REST_API_ID,
viewerResourceId: process.env.VIEWER_RESOURCE_ID,
oauthResourceId: process.env.OAUTH_RESOURCE_ID,
httpMethod: 'GET',
ngrokToken: process.env.NGROK_TOKEN,
slackClientId: process.env.SLACK_CLIENT_ID,
slackClientSecret: process.env.SLACK_CLIENT_SECRET,
wsId: process.env.WORKSTATION_ID,
privateKey: process.env.LIVE_PRIVATE_KEY,
privateKey: process.env.PRIVATE_KEY,
debug: Boolean(process.env.DEBUG),
isMac: Boolean(process.env.IS_MAC),
};

const disk = new Stream('bushitsuchan');
const liveServer = new RtmpServer(1935);
liveServer.run();
console.log(`RTMP server listening on port ${1935}`);

const disk = new Stream(
config.isMac ? `${__dirname}/hls` : '/dev/shm',
'bushitsuchan',
config.isMac,
);
console.log(`Regarding directory ${disk.mountPath} as RAM DISK`);

disk
.run()
.run(config.isMac)
.then(async (mountPath) => {
const ngrokUrl = await ngrok.run(process.env.NGROK_TOKEN);
const awsUrl = await aws.run(config, ngrokUrl);
// console.log(`Remote URL: ${awsUrl}`);
console.log(`Please put HLS files in ${mountPath}`);
let input;
if (config.isMac) {
input = 'ffmpeg -f avfoundation -framerate 30 -re -i 0 -r 10';
} else {
input = 'ffmpeg -i /dev/video0';
}
daemon(
`${input} -vcodec libx264 -pix_fmt yuv420p -preset veryfast -tune zerolatency,stillimage,film -vb 2500k -vf "drawtext=text='%{localtime}':[email protected]:x=0:y=h-lh*1.2:fontsize=24" -f flv rtmp://localhost:${1935}/live/bushitsuchan`,
);

daemon(
`ffmpeg -i rtmp://localhost:1935/live/bushitsuchan -hls_flags delete_segments -codec:v copy -g 40 -f hls ${mountPath}/output.m3u8`,
);

let ngrokUrl;
let awsUrl;

const server = new Server(ngrokUrl, awsUrl, mountPath, config);
server.run();
if (config.debug) {
ngrokUrl = null;
awsUrl = null;
} else {
ngrokUrl = await ngrok.run(config.ngrokToken, 3000);
console.log(`Forwarding ${ngrokUrl} -> localhost:${3000}`);

awsUrl = await aws.run(config, ngrokUrl);
console.log(`Remote URL: ${awsUrl}`);
}

const server = new Server(
ngrokUrl,
awsUrl,
mountPath,
config,
`rtmp://localhost:1935/live/${'bushitsuchan'}`,
);
server.run(3000).then(() => console.log(`Express app listening on port ${3000}`));
})
.catch((e) => {
disk.close();
console.error(e);
disk.close();
});
2 changes: 0 additions & 2 deletions ngrok.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ const ngrok = require('ngrok');
module.exports.run = async (token, port = 3000) => {
await ngrok.authtoken(token);
const url = await ngrok.connect(port);

console.log(`Forwarding ${url} -> localhost:${port}`);
return url;
};
Loading

0 comments on commit 8ae420f

Please sign in to comment.