Node.js sending audio file and allowing user to seek - javascript

I am trying to create an app that allows the users to dynamically change the track they are listening to. I am using sails.js on top of node. The issue that I am having is that when the user try to seek to a time in the song before or after the current time the song will start over.
this is the latest code that i have tried to implement on the server.
'index': function (request, response) {
var path = require('path');
var fs = require('fs');
var filePath = path.join('path\to\folder','music.mp3')
var stat = fs.statSync(filePath);
response.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
fs.readFile(filePath,function (err,data) {
response.send(data);
});
}

Found a media streaming module for node: https://github.com/obastemur/mediaserver
run:
npm install mediaserver --save
adjusted code:
'index': function (request, response) {
var AUDIOFILE = 'path/to/audio.mp3'
ms.pipe(request,response,AUDIOFILE);
}
Simply awesome module by https://github.com/obastemur. Hope this helps anyone who was having a similar issue.

Related

Connect node app and server + post image to server

I have a very basic question about a node application, and a question about HTTP requests. It's the first time I create a node app with server, and I just can't seem to get the different components to work together.
This is my server.js
var express = require('express');
var multer = require('multer');
const request = require('request');
const upload = multer({dest: __dirname + '/uploads/images'});
const app = express();
const PORT = 3000;
app.use(express.static('public'));
app.post('/upload', upload.single('photo'), (req, res) => {
if(req.file) {
res.json(req.file);
}
else throw 'error';
});
app.listen(PORT, () => {
console.log('Listening at ' + PORT );
});
Then I have a file app.js with a motion-detection system. Every time motion is detected, a picture is taken. This all works fine.
Then the picture should be sent to the server. This is what I can't figure out.
I created a function toServer() that should post the detected data to the server
const request = require('request');
function toServer(data) {
const formData = {
// Pass data via Buffers
my_buffer: data,
// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
};
request.post({url:'http://localhost:3000/upload', formData: formData}, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('Upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
};
Problem 1: when running the server.js on localhost:3000, it doesn't find any of the scripts loaded in index.html nor my app.js.
Problem 2: when running the index.html on live-server, all scripts are found, but i get the error "request is not defined".
I am pretty sure there is some basic node setup thing I'm missing.
The solution for toServer() might be more complicated.
Thanks for your time,
Mustard Shaper
Problem 1:
this could happen because you have not specified to render your index.html.
for example:
res.render('index')
if it's not because of the single quotes in upload.single('photo') try double quotes.
Another possible error could be that you are missing a default display engine setting.
an example: https://www.npmjs.com/package/hbs
Problem 2:
it may be because you are missing the header
var request = require('request');
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'http://localhost',
body: "example"
}, function(error, response, body){
console.log(body);
});
See more at https://expressjs.com/

Error using fastify-multer to upload images

I am trying to use the fastify-multer plugin to upload files to the server and I am able to successfully get the images uploaded to the folder.
The problem is my app crashes.
I used the fastify-cli generated structure and I am running it as a standalone server as mentioned in the README.md here.
I am writing it as a fastify plugin.
"use strict";
const fp = require("fastify-plugin");
module.exports = fp(function(fastify, opts, next) {
fastify.decorate("uploadImage", function(request) {
const path = require("path");
const multer = require("fastify-multer");
var storage = multer.diskStorage({
destination: path.join(path.join(__dirname + "/uploads/")),
filename: function(request, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage }).single("myImage");
upload(request, function(err) {
if (err) {
console.log(err);
} else {
console.log("Saved...");
return { saved: true };
}
});
});
next();
});
And here is the error I get :
Hi looked into your issue. You are using fastify-multer in the wrong way.
Invoking multer({ storage }).single("myImage") you are creating a fastify's preHandler hook that accepts 3 specific parameters. You can find more on the offical documentation. A simple working example could be the one you can see at fastify-multer:
const server = fastify()
// register fastify content parser
server.register(multer.contentParser)
server.route({
method: 'POST',
url: '/profile',
preHandler: upload.single('avatar'),
handler: function(request, reply) {
// request.file is the `avatar` file
// request.body will hold the text fields, if there were any
reply.code(200).send('SUCCESS')
}
})
If you need more help just provide me a repro repo on github and I'll try to figure out what is the best solution for your case.
Let me know! :)

Missing ; before statement (Jira Addon - oAuth)

I get the error:
[WARNING] File encoding has not been set, using platform encoding windows-1252, i.e. build is platform dependent!
[INFO] Compiling javascript using YUI
[ERROR] missing ; before statement let privateKeyData = fs.readFileSync('location','utf-8');
As shown I have put the ; before let. I don't understand the error. I am creating an add-on for Jira. I started the JS file via cmd and it worked. However when I want to package the project I get that error. Please help.
jQuery(function($) {
var initmyConfluenceMacro = function() {
$(".myConfluenceMacro").each(function() {
const request = require('request');
const fs = require('fs');
let privateKeyData = fs.readFileSync('filelocation', 'utf-8');
const oauth = {
consumer_key: 'mykey',
consumer_secret: privatkey,
token: 'mytoken',
token_secret: 'tokensecret',
signature_method: 'signaturemethod'
};
request.get({
url: 'thelink',
oauth: oauth,
qs: null,
json: true
}, function(e, r, user) {
console.log(user)
});
var html = "output";
$(this).html(html);
});
};
$(document).ready(function() {
initmyConfluenceMacro();
});
});
The problem for the error is
const fs = require('fs');
fs is for (as on their page) security reasons removed from Atlassian and cannot be used. My workaround was to use the velocity template, in order to import the file, and then to parse it to the js file.
I hope this helps. If someone has other ideas please let me know.

Can Tedious connection and request event listeners be put in a separate module for Node.js?

This is my first ever question on here so please excuse any abnormalities in etiquette.
I am new to Node.js and backend programming in general.
Right now I am using Node and Tedious to connect to a local SQL server. I'd like to keep my main.js file clean and so am trying to put everything related to my SQL connection in a separate js file. Below would be the simplest possible form I have for my main.js.
var http = require('http');
var sqlmodule = require('./SQLconnection');
http.createServer(function (req, res) {
sqlmodule.makeConnection();
}).listen(8080);
I then have my SQLconnection.js file.
var Connection = require('tedious').Connection;
exports.makeConnection = function () {
var config = {
userName: 'XXXXXX',
password: 'XXXXXX',
server: 'XXXXXX'
};
var connection = new Connection(config);
};
//The below code is my event listener but I don't know how
//to incorporate it as part of the module.
connection.on('connect', function(err) {
if (err) {
console.error('Connection error', err);
} else {
console.log('Connected');
}
});
I have no problems when the listener isn't present in the file, but I can't find a way to have it part of the SQLconnection.js module. I've tried adding exports and module.exports before it in a few ways but to no success. It listening for an event and not being a normal function is stumping me.
How would I go about getting the event listeners in the separate file?
I'm also trying to go about this as vanilla as possible, so I'm just using Node.js and Tedious at this point.
change
exports.makeConnection = function () {
to
function makeConnection() {
...
module.exports = {makeConnection}
As an additional change, you need to put your connection listener in the sames scope as the connection variable. Personally, I would also have makeConnection return a Promise with the connection so you are not operating on a connection that has failed/not yet connected. Something like
var Connection = require('tedious').Connection;
function makeConnection() {
var config = {
userName: 'XXXXXX',
password: 'XXXXXX',
server: 'XXXXXX'
};
return new Promise((resolve, reject) => {
var connection = new Connection(config);
connection.on('connect', function(err) {
if (err) return reject(err);
resolve(connection);
});
}
};
module.exports = {makeConnection}

Create and Send Zip file -NODE JS

I'm trying to create and then send zip file to client. I know how to create it but I've got a problem with send it to client. I tried many ways.
I'm sending POST request from Client and as response I want to send a file.
This is my server-site example code
var Zip = require('node-zip');
router.post('/generator', function(req, res, next) {
var zip = new Zip;
zip.file('hello.txt', 'Hello, World!');
var options = {base64: false, compression:'DEFLATE'};
fs.writeFile('test1.zip', zip.generate(options), 'binary', function (error) {
console.log('wrote test1.zip', error);
});
res.setHeader('Content-disposition', 'attachment; filename=test1.zip');
res.download('test1.zip');
}
});
I also tried something like this:
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
var filestream = fs.createReadStream(file);
filestream.pipe(res);
I tried to use such libraries as:
node-zip
archiver
Can anyone explain me how to do that ?
This module works fine too: https://www.npmjs.com/package/adm-zip
Example without creating temporary zip file in server:
var AdmZip = require('adm-zip');
router.get('/zipFilesAndSend', function(req, res) {
var zip = new AdmZip();
// add local file
zip.addLocalFile("./uploads/29/0046.xml");
// get everything as a buffer
var zipFileContents = zip.toBuffer();
const fileName = 'uploads.zip';
const fileType = 'application/zip';
res.writeHead(200, {
'Content-Disposition': `attachment; filename="${fileName}"`,
'Content-Type': fileType,
})
return res.end(zipFileContents);
});
Try this express-easy-zip npm package to generate a zip file from a local folder path and send it as a download to the client.
var zip = require('express-easy-zip');
var app = require('express')();
app.use(zip());
app.get('my-route/zip', async function(req, res) {
var dirPath = __dirname + "/uploads";
await res.zip({
files: [{
path: dirPath,
name: 'Package'
}],
filename: 'Package.zip'
});
});
I haven't worked with node-zip or archiver before (I usually just use the built-in zlib module), but one thing I noticed right away is that you should place res.download inside the callback of writeFile. That way it will only send the file once it has been fully written to disk.
fs.writeFile('test1.zip', zip.generate(options), 'binary', function (error) {
res.download('test1.zip');
});
I hope this solution works for you, if it doesn't feel free to comment.
Also, I think res.download sets the Content-disposition header for you, you don't need to set it manually. Not 100% sure on that one though.
Above solutions work.(above solutions generate zip and send it to frontend as data in response. In order to make it as downloadable following code will work) I was using express-zip. It is compressing files and sending data to frontend from backend(node). But in frontend I was getting only data in response. In my case I want user can be able to download the zip which sent by server. To solve this I followed following approach. For generating download window in browser i used downloadjs (we can follow another approach but i find this easy)
Front-End
const download = require('downloadjs')
return axios({
url:process.env.API_HOST+'/getuploadedfiles',
method:'get',
headers:{
'Content-Type': 'multipart/form-data',
withCredentials:true,
},
responseType:'arraybuffer' // If we don't mention we can't get data in desired format
})
.then(async response => {
console.log("got al files in api ");
let blob = await new Blob([response.data], { type: 'application/zip' }) //It is optional
download(response.data,"attachement.zip","application/zip") //this is third party it will prompt download window in browser.
return response.data;
})
Backe-End
const zip = require('express-zip');
app.use('/getuploadedfiles',function(req,res){
res.zip([
{path:'/path/to/file/file2.PNG',name:'bond.png'},
{path:'/path/to/file/file1.PNG',name:'james.png'}
])

Categories

Resources