How to use webtorrent in browser? - javascript

I have some trouble with the the example showed in https://github.com/feross/webtorrent#usage
I'm trying to use the code in browser. So I first create a file called app.js
app.js
var WebTorrent = require('webtorrent')
var concat = require('concat-stream')
var client = new WebTorrent()
console.log('Hi there');
client.download('magnet:?xt=urn:btih:XXXXXXXX', function (torrent) {
// Got torrent metadata!
console.log('Torrent info hash:', torrent.infoHash)
torrent.files.forEach(function (file) {
// Get the file data as a Buffer (Uint8Array typed array)
file.createReadStream().pipe(concat(function (buf) {
// Append a link to download the file
var a = document.createElement('a')
a.download = file.name
a.href = URL.createObjectURL(new Blob([ buf ]))
a.textContent = 'download ' + file.name
document.body.appendChild(a)
}))
})
})
Then I type command browserify app.js > bundle.js so that can make code work for browser. I create another file called index.html:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>test</title>
<script src="bundle.js"></script>
</head>
<body id="home">
<h1>test</h1>
</body>
</html>
From the console I can only see "Hi there". It seems that the client.download() function didn't work. Why this happened? I'm new to browserify, is there anything wrong with the command which I use?

WebTorrent can only download torrents that are explicitly seeded to the WebTorrent network. Torrent clients need to support WebRTC to peer with web browsers. Currently, no clients support it but you can use http://instant.io to start seeding a new torrent and try downloading it using the WebTorrent library in your application. Enable debug logs on http://instant.io by setting `localStorage.debug = '*' to get the info-hash of the torrent.
You can also learn more here:
How does WebTorrent work? (https://github.com/feross/webtorrent/issues/39)
WebRTC BEP (https://github.com/feross/webtorrent/issues/175)

Related

Is it possible to share variables between a node.js file and html/javascript file?

I'm doing a project consisting of two parts. One part is javascript/html and uses a CDN-hosted pose-estimation library (ml5) along with p5.js. The other part is Node.JS and uses an npm-installed library (osc.js). I would like to take variables from the hosted/html section and pass them to the Node.JS project. How can I do this?
I've tried downloading and adapting the ml5 library and including it in my node project, but I've had no luck with this as it is designed for the browser.
My HTML file:
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>
<script src="https://unpkg.com/ml5#0.1.3/dist/ml5.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
...and so on....
My associated javascript file (exerpt), using the ml5 library:
let video;
let poseNet;
let noseX = 0;
function setup() {
// some setup code here
poseNet = ml5.poseNet(video, modelReady);
}
function gotPoses(poses) {
if (poses.length > 0) {
let noseY = poses[0].pose.keypoints[0].position.x;
}
}
My Node.JS file (which sends data over OSC/UDP), uses the node library OSC:
var osc = require("osc");
// some code here
setInterval(function() {
var msg = {
address: "/hello/from/oscjs",
args: [
{
type: "s",
value: noseY
}
]
};
// more code here
I would like to be able to call the noseY variable from within the Node.JS file, but I see no way to grab it from the html/javascript section. There exists a ml5 package for npm, but it is still under development and doesn't work for me. I have also looked for browser-based alternatives to the OSC library, but could not find any suitable alternatives.

Using node packages in browser with browserify - Uncaught ReferenceError: fileType is not defined

I am trying to use the file-type npm package in the browser.
So far I have not been able to get the example code to execute as it throws the following error: Uncaught ReferenceError: fileType is not defined
(Example code as specified here: https://github.com/sindresorhus/file-type)
const xhr = new XMLHttpRequest();
xhr.open('GET', 'unicorn.png');
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
fileType(new Uint8Array(this.response));
//=> {ext: 'png', mime: 'image/png'}
};
xhr.send();
So far I have tried to include the file-type package in my index.html in a script tag however this did not work. A quick google revealed to me I should be using browserify in order to use npm packages in the browser, from here I:
I created a file called deps.js and added the file-type package like so
const fileType = require("file-type");
I then created a bundle from deps.js by running:
browserify deps.js -o bundle.js
I then added bundle.js to index.html like so:
<script src="bundle.js"></script>
<script src="main.js"></script>
For reference here is code from: index.html, main.js and deps.js:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="bundle.js"></script>
<script src="main.js"></script>
</body>
</html>
//main.js
const xhr = new XMLHttpRequest();
xhr.open('GET', 'iris.webp');
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
fileType(new Uint8Array(this.response));
//=> {ext: 'png', mime: 'image/png'}
};
xhr.send();
//deps.js
const fileType = require("file-type");
If working correctly I would expect fileType to return an object that looks like:
{
ext: 'webp',
mime: 'image/webp'
}
If anybody could tell me where I am going wrong it would be highly appreciated. Many thanks.
According to the example on the front page of browserify You still need to make the fileType object.
From what you've posted, deps.js makes a fileType object, but when you run it from the browser deps.js gets skipped.
To use browserify as they intentyou should put the line const fileType = require("file-type"); at the top of main.js and run browserify against main.js
Alternatively include deps.js like so:
<script src="bundle.js"></script>
<script src="deps.js"></script>
<script src="main.js"></script>

How to Access Local JavaScript File from a Cloud Functions HTML File?

I am trying to simply access a JavaScript file from within an HTML file using the script src attribute, and I have been unable to do so. Both files are in my functions folder.
I have the following Cloud Function index.js file in my functions folder:
const functions = require('firebase-functions');
const db = require('./admin');
var viewerApp = require('./viewerApp');
exports.view = functions.https.onRequest(viewerApp);
the viewApp.js file looks like this:
const express = require("express");
const fs = require('fs');
const viewerApp = express();
module.exports =
viewerApp.get('/:collection_name/:id', (req, res) =>
{
var viewerHTML = fs.readFileSync('./viewerApp.html').toString();
var id = req.params.id;
var collection_name = req.params.collection_name;
var rendered_HTML = eval(viewerHTML);
res.send(rendered_HTML);
}
)
You will notice the eval(viewerHTML) statement, which refers to a separate html file called viewerApp.html, which basically contains a template literal and looks like so:
<!DOCTYPE html>
<html lang="en">
<body>
...
</body>
</html>
(if someone has a better suggestion for separating the HTML into a separate file while being able to use ${variables} that would be helpful as well, as eval() is not ideal and perhaps is part of what is causing my problem)
The above works fine, except that I cannot figure out how to reference a JavaScript file located in the same functions folder, which means I would need to include all my JavaScript in the viewerApp.html file, which will be a mess.
I have tried all these possibilities in the viewerApp.html file (to try and refer to a JavaScript file called test.js):
<script src="./test.js"></script>
<script src="/test.js"></script>
<script src="test.js"></script>
<script src=test.js></script>
All of the above yield the following error in the console:
Uncaught SyntaxError: Unexpected token < test.js:2
(I get the same error if I try and refer to a filename that doesn't exist so I suspect a problem in the file path or limitation on the ability to access the local file system)
I don't know what to make of the error being related to a < character, as the content of test.js is simply:
console.log("logging happened");
Any assistance would be MUCH appreciated. Thank you!!
The problem in the end was that I did not initialize and configure firebase hosting which seems to be what allows html/js/css and other static files to be accessible in HTML returned from the cloud function. Once I did that and setup the public folder, I was able to refer to the test.js file by putting it in the public folder. That plus addition tweaks to the rewrite section of the firebase.json file, and I was all set. Following this video helped a lot and contains all the required steps.

Unable to connect to Openfire server from the script running browser side

At first, I was connecting to Openfire using following script.
const {Client} = require('#xmpp/client')
const client = new Client()
client.start('xmpp://localhost:5222').catch(err => {
console.error('start failed', err)
})
client.handle('authenticate', authenticate => {
return authenticate('gabbar', 'gabbar#123')
})
But it shows me an error 'require is not defined'. so I searched the internet and found that browserify could do my work. so I made the bundle.js file using index.js of my HTML page and included it in the HTML page.
<head>
<meta charset="UTF-8"/>
<title>xmpp.js example</title>
<script src="bundle.js"></script>
<!-- <script src="index.js"></script>-->
</head>
but then I am getting the error
no compatible connection method found
Is anybody can tell any other way of doing it. I tried also same as given in example directory of xmpp.js client package, but that is giving me error like XMPP is not a function. Following is the code which I wrote after looking at example files.
index.js
const {xmpp, xml} =
typeof require === 'undefined' ? window.xmpp : require('#xmpp/client') // For you; require('#xmpp/client')
const {client} = xmpp()
client.start('xmpp://localhost:5222').catch(err => {
console.error('start failed', err)
})
client.handle('authenticate', authenticate => {
return authenticate('gabbar', 'gabbar#123')
})
sample.html
<head>
<meta charset="UTF-8"/>
<title>xmpp.js example</title>
<script src="node_modules/xmpp.js/dist/xmpp.min.js"></script>
<script src="index.js"></script>
</head>
these are the two ways I tried connecting to openfire from the browser side but none of them worked for me. please, can anybody tell me what I am doing wrong or any other possible better way of doing this?
xmpp:// is not supported in the browser. Only ws:// (websockets) is supported in browser. If the server supports websockets, you would do something like:
client.start('ws://domain:port) or client.start('ws://domain:port/xmpp-websockets)
The other option is to use Node not in a browser. Which would be accomplished by running node on it's own without a browser or running that code in the background process of Electron (same as just running node by itself, but you can communicate with the renderer process to interact with a UI)

Downloading multiple files and zip - Chrome extension

Is it possible to download multiple images into the sandbox file system (without the "save as" dialog box, or at-max one saveas dialog) ?
after downloading them, i'd like to ZIP them into one.. is there any javascript archive library?
Thanks in advance..
You can use zip.js for this.
It does already have API for fetching contents to be zipped from HTTP (cf. zip.HttpReader constructor) and for writing generated zip on HTML5 filesystem (cf. zip.FileWriter constructor).
Here is an example using the filesystem API:
index.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zip JSON data from the BBC into HTML5 FileSystem</title>
</head>
<body>
<script src="zip.js"></script>
<script src="zip-fs.js"></script>
<script src="zip-ext.js"></script>
<script src="example.js"></script>
</body>
</html>
example.js file:
// create a zip virtual filesystem
var fs = new zip.fs.FS();
// add some files into the zip filesystem
// add the "bbc-music.json" file in the root directory
fs.root.addHttpContent("bbc-music.json",
"http://www.bbc.co.uk/programmes/genres/music.json");
// add the "bbc-learning.json" file in the root directory
fs.root.addHttpContent("bbc-learning.json",
"http://www.bbc.co.uk/programmes/genres/learning.json");
// create a file named "test.zip" in the root directory of the HTML5 filesystem
createFile("test.zip", function(fileEntry) {
// export the zip content into "test.zip" file
fs.root.exportFileEntry(fileEntry, function() {
console.log("done");
});
});
// function to create a file in the HTML5 temporary filesystem
function createFile(filename, callback) {
webkitRequestFileSystem(TEMPORARY, 4 * 1024 * 1024, function(fs) {
fs.root.getFile(filename, { create : true }, callback);
});
}
You can access images as regular parts of some web-pages or download them separately by means of XMLHTTPRequests. After this you can zip them in a single archive using JSZip JavaScript library. The zip can be stored as a file without a "Save As" dialog (try the example on the site). Though I'm not sure why you need the sandbox.
There exist other JavaScript libraries for zipping, for example, some are mentioned in other SO answer.

Categories