This repository has been archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Add browser example for ReadableStreams
feat: Allows for byte offsets when using ipfs.files.cat and friends to request slices of files
- Loading branch information
1 parent
c1e8db1
commit 580c1f3
Showing
8 changed files
with
245 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Streaming video from IPFS using ReadableStreams | ||
|
||
We can use the execllent [`videostream`](https://www.npmjs.com/package/videostream) to stream video from IPFS to the browser. All we need to do is return a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)-like object that contains the requested byte ranges. | ||
|
||
Take a look at [`index.js`](./index.js) to see a working example. | ||
|
||
## Running the demo | ||
|
||
In this directory: | ||
|
||
``` | ||
$ npm install | ||
$ npm start | ||
``` | ||
|
||
Then open [http://localhost:8888](http://localhost:8888) in your browser. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/> | ||
<title><%= htmlWebpackPlugin.options.title %></title> | ||
<style type="text/css"> | ||
|
||
body { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
#container { | ||
display: flex; | ||
height: 100vh; | ||
} | ||
|
||
pre { | ||
flex-grow: 2; | ||
padding: 10px; | ||
height: calc(100vh - 45px); | ||
overflow: auto; | ||
} | ||
|
||
#form-wrapper { | ||
padding: 20px; | ||
} | ||
|
||
form { | ||
padding-bottom: 10px; | ||
display: flex; | ||
} | ||
|
||
#hash { | ||
display: inline-block; | ||
margin: 0 10px 10px 0; | ||
font-size: 16px; | ||
flex-grow: 2; | ||
padding: 5px; | ||
} | ||
|
||
button { | ||
display: inline-block; | ||
font-size: 16px; | ||
height: 32px; | ||
} | ||
|
||
</style> | ||
</head> | ||
<body> | ||
<div id="container"> | ||
<div id="form-wrapper"> | ||
<form> | ||
<input type="text" id="hash" placeholder="Hash" disabled /> | ||
<button id="gobutton" disabled>Go!</button> | ||
</form> | ||
<video id="video" controls></video> | ||
</div> | ||
<pre id="output" style="display: inline-block"></pre> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
'use strict' | ||
|
||
/* eslint-env browser */ | ||
|
||
const Ipfs = require('../../') | ||
const videoStream = require('videostream') | ||
const repoPath = 'ipfs-' + Math.random() | ||
const ipfs = new Ipfs({ repo: repoPath }) | ||
|
||
const log = (line) => { | ||
document.getElementById('output').appendChild(document.createTextNode(`${line}\r\n`)) | ||
} | ||
|
||
log('Initialising IPFS') | ||
|
||
let stream | ||
|
||
const cleanUp = () => { | ||
if (stream && stream.destroy) { | ||
stream.destroy() | ||
} | ||
} | ||
|
||
ipfs.on('ready', () => { | ||
const videoElement = createVideoElement() | ||
|
||
log('Adding video file') | ||
|
||
addVideoFile('/video.mp4') | ||
.then(hash => { | ||
log(`Added file with hash ${hash}`) | ||
|
||
const hashInput = document.getElementById('hash') | ||
const goButton = document.getElementById('gobutton') | ||
|
||
hashInput.value = hash | ||
|
||
goButton.onclick = function () { | ||
videoStream({ | ||
createReadStream: function (opts) { | ||
const start = opts.start | ||
|
||
// The videostream library does not always pass an end byte but when | ||
// it does, it wants bytes between start & end inclusive. | ||
// catReadableStream returns the bytes exclusive so increment the end | ||
// byte if it's been requested | ||
const end = opts.end ? start + opts.end + 1 : undefined | ||
|
||
log(`Asked for data starting at byte ${start} and ending at byte ${end}`) | ||
|
||
cleanUp() | ||
|
||
// We will write the requested bytes into this stream | ||
stream = ipfs.files.catReadableStream(hashInput.value.trim(), start, end) | ||
|
||
return stream | ||
} | ||
}, videoElement) | ||
|
||
return false | ||
} | ||
|
||
hashInput.disabled = false | ||
goButton.disabled = false | ||
}) | ||
}) | ||
|
||
const addVideoFile = (path) => { | ||
return fetch(path) | ||
.then(response => response.arrayBuffer()) | ||
.then(buffer => ipfs.files.add(Buffer.from(buffer))) | ||
.then(result => result.pop().hash) | ||
} | ||
|
||
const createVideoElement = () => { | ||
const videoElement = document.getElementById('video') | ||
videoElement.addEventListener('loadedmetadata', () => { | ||
log('Video metadata loaded') | ||
|
||
videoElement.play() | ||
}) | ||
videoElement.addEventListener('loadeddata', () => { | ||
log('First video frame loaded') | ||
}) | ||
videoElement.addEventListener('loadstart', () => { | ||
log('Started loading video') | ||
}) | ||
|
||
return videoElement | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "browser-videostream", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"build": "webpack", | ||
"start": "npm run build && curl https://www.html5rocks.com/en/tutorials/video/basics/devstories.mp4 -o dist/video.mp4 && http-server dist -a 127.0.0.1 -p 8888" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"html-webpack-plugin": "^2.30.1", | ||
"http-server": "^0.11.1", | ||
"uglifyjs-webpack-plugin": "^1.2.0", | ||
"webpack": "^3.11.0" | ||
}, | ||
"dependencies": { | ||
"videostream": "^2.4.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use strict' | ||
|
||
const path = require('path') | ||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') | ||
const HtmlWebpackPlugin = require('html-webpack-plugin') | ||
|
||
module.exports = { | ||
devtool: 'source-map', | ||
entry: [ | ||
'./index.js' | ||
], | ||
plugins: [ | ||
new UglifyJsPlugin({ | ||
sourceMap: true, | ||
uglifyOptions: { | ||
mangle: false, | ||
compress: false | ||
} | ||
}), | ||
new HtmlWebpackPlugin({ | ||
title: 'IPFS Videostream example', | ||
template: 'index.html' | ||
}) | ||
], | ||
output: { | ||
path: path.join(__dirname, 'dist'), | ||
filename: 'bundle.js' | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters