Writing a Text to Speech file as an MP3 - IBM Watson - javascript

I'm following the documentation for the Node.JS implementation of the IBM Watson Text-to-Speech API.
I want to output the resultant file into MP3 format. The documentation recommends augmenting the base code but I'm not sure how to do that. My code is rendering unplayable MP3s.
Here is what it says in the documentation:
textToSpeech.synthesize(synthesizeParams)
.then(response => {
// The following line is necessary only for
// wav formats; otherwise, `response.result`
// can be directly piped to a file.
return textToSpeech.repairWavHeaderStream(response.result);
})
.then(buffer => {
fs.writeFileSync('hello_world.wav', buffer);
})
.catch(err => {
console.log('error:', err);
});
As it says, response.result should be directly piped to a file. This is one of my many attempts (that renders an error).
textToSpeech
.synthesize(synthesizeParams)
.then(response => {
fs.writeFileSync('Hello.mp3', response.result)
})
.catch(err => {
console.log('error:', err)
})
How can I output the text-to-speech input as an MP3?

Provided your params are requesting an mp3 file, this will be the accept parameter, then your code looks ok. So if the output file isn't being recognised as an audio, then it is most likely a text file containing an error message. This error message will indicate what is wrong, which most likely will be an unauthorised message.
I take it that your catch error block isn't logging anything.

Related

Fetching error on my chrome console I tried using different browses as well but still not solved

Fetching error on my chrome console I tried using different browsers as well but still not solved
fetch('https://api.cryptonator.com/api/ticker/btc-usd')
.then(res => {
console.log("Response Awaits to Parse");
})
.then(data => {
console.log("Data Parsed");
console.log(data.ticker.price);
})
.catch(e => {
console.log("Error NO!!!", e);
})
enter image description here
enter image description here
You are getting a 503 Error, which means the server is not ready to handle the request. Basically it means the problem is on the server side, not on you app. Check here for more info https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503?retiredLocale=uk

Javascript fetch stopped working for local files

I have a tiny HTML/CSS/JS app I use to read and play certain types of files. I have no need for it to be on a server.
As of yesterday, it "worked." Suddenly, today I'm getting an error about using fetch with local files. I did make some settings changes on my Windows 10 laptop.
abcjs-init.js:15 Fetch API cannot load file:///E:/OneDrive/Documents/ABCJS-Minimal-Editor-Notation-Player/tunes/tune_list.txt. URL scheme "file" is not supported.
This is my code:
fetch(tunes_list_path, {mode: 'no-cors'})
.then(response =>
{
console.log("response:", response);
return response
})
.then(data =>
{
console.log("data:", data)
return data.text()
})
.then(Normal =>
{
console.log("got tunelist");
console.log("tune_list");
let tune_list = Normal.split("\n").sort();
addTunesToSelector(tune_list);
})
.catch(err =>
{
console.log('Fetch problem show: ' + err.message);
});
Further up is: let tunes_list_path = "tunes/tune_list.txt";.
The index.html loads fine. I can also view the file in the error directly with its URL. So it is visible to the browser.
Do I need to enable something in my browser? Add something to the fetch call?
Aha! I had changed a setting in Firefox that allowed COORS with local files: privacy.file_unique_origin.
I apparently erased that setting during my OS maintenance.
This solution is only for FF. There may be an equivalent setting for Chromium-based browsers.

Problems Downloading files using Dropbox JavaScript SDK

I need to figure out where my files are downloading when I use the filesDownload(). I don't see an argument for file destination. Here's my code:
require('isomorphic-fetch');
var Dropbox = require('dropbox').Dropbox;
var dbx = new Dropbox({ accessToken: 'accessToken', fetch});
dbx.filesDownload({path: 'filepath}).
then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
I'm getting a successful callback when I run the code but I don't see the file anywhere.
I need to know where my files are downloading to and how to specify the file destination in my function.
Thanks,
Gerald
I've used the function as described in the SDK's documentation (http://dropbox.github.io/dropbox-sdk-js/Dropbox.html#filesDownload__anchor) but I have no idea where my file goes.
Expected Result: Files are downloaded to Dropbox to path that I have designated.
Actual Results: I get a successful callback from Dropbox but I cannot find the files downloaded.
In Node.js, the Dropbox API v2 JavaScript SDK download-style methods return the file data in the fileBinary property of the object they pass to the callback (which is response in your code).
You can find an example of that here:
https://github.com/dropbox/dropbox-sdk-js/blob/master/examples/javascript/node/download.js#L20
So, you should be able to access the data as response.fileBinary. It doesn't automatically save it to the local filesystem for you, but you can then do so if you want.
You need to use fs module to save binary data to file.
dbx.filesDownload({path: YourfilePath})
.then(function(response) {
console.log(response.media_info);
fs.writeFile(response.name, response.fileBinary, 'binary', function (err) {
if (err) { throw err; }
console.log('File: ' + response.name + ' saved.');
});
})
.catch(function(error) {
console.error(error);
});

How to add an album cover to an mp3 stream using FFmpeg?

I'm having a bit of an issue and I'd really appreciate it if I could get some insights.
What I am trying to do is to add an album cover to the mp3 file that will be downloaded from the front-end.
Context
I'm downloading a video stream from YouTube and converting it to mp3 using fluent-ffmpeg.
To get the video I use the ytdl npm module.
I then pipe this stream to the front-end.
What I've found
fluent-ffmpeg offers either pipe() or saveToFile().
What I figured is that when I use the saveToFile() function and actually save my stream into an mp3 file, it works, I do get the album cover.
But when I pipe the stream to front-end or even into a file, the song is saved properly into a file but without the album cover.
Here is my code
Back-end (NodeJS)
let video = ytdl(`http://youtube.com/watch?v=${videoId}`, {
filter: (format) => format.container === 'mp4' && format.audioEncoding,
quality: 'lowest'
});
let stream = new FFmpeg()
.input(video)
.addInput(`https://i.ytimg.com/vi/${videoId}/default.jpg`)
.outputOptions([
'-map 0:1',
'-map 1:0',
'-c copy',
'-c:a libmp3lame',
'-id3v2_version 3',
'-metadata:s:v title="Album cover"',
'-metadata:s:v comment="Cover (front)"'
])
.format('mp3');
And then piping it to my front-end.
stream.pipe(res);
stream
.on('end', () => {
console.log('******* Stream end *******');
res.end.bind(res);
})
.on('error', (err) => {
console.log('ERR', err);
res.status(500).end.bind(res);
});
Front-end (React)
axios.get(url)
.then(res => {
axios(`${url}/download`, {
method: 'GET',
responseType: 'blob'
})
.then(stream => {
const file = new Blob(
[stream.data],
{ type: 'audio/mpeg' });
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
})
.catch(err => {
console.log('ERROR', err);
});
})
.catch(err => {
console.log('ERROR', err);
});
Unfortunately, it seems there is no possible solution to complete this task with streams. I've researched a lot but found only an explanation of why we can't do this with FFmpeg and piping stream. njoyard wrote the following:
Actually this problem is not specific to Windows. Most formats write
stream information (duration, bitrate, keyframe position...) at the
beginning of the file, and thus ffmpeg can only write this information
when its output is seekable (because it has to finish processing
streams to the end before knowing what to write). Pipes are not
seekable, so you won't get this information when using an output pipe.
As for your note about the output format, ffmpeg determines the output
format from the output file extension, which is not possible with
pipes; that's why you have to specify the output format explicitly.
Here is a link to find it by yourself: https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/issues/159
So, the only solution I see is saving file with saveToFile() method and attaching it to response.

error uploading to cloud storage using a cloud function

I am trying to upload files to google cloud storage using a cloud function which is triggered by HTTP. However when the cloud function sends the file to be uploaded I often (although not always) get the following error
ERROR uploading to storage: { ApiError: Anonymous caller does not have storage.objects.create access to bucket_name/folder/test.jpg.
I am not sure why this error occurs - and why only some of the time
Here is the code:
const storage = require('#google-cloud/storage')();
function uploadToStorage(filepath, folder, filename) {
const options = {
destination: bucket.file(`${folder}/${filename}`),
public: false,
resumable: false
};
storage
.bucket(BUCKET_NAME)
.upload(filepath, options)
.then(function () {
console.log(`${filename} uploaded to ${BUCKET_NAME}`);
})
.catch((err) => {
console.error('ERROR uploading to storage: ', err);
});
}
Thanks
I had the same error after adding a return statement at the end of my function that performed file deletes on storage objects. This is what I was doing:
Make a database call to get some data
Once that request comes back, delete some files out of cloud storage (GCS)
The code structurally looked like this:
deleteStuffOutStorage() {
admin.firestore().doc(`My-doc-ref`).get()
.then(snapshot => {
// Do the deleting here {Interacting with GCS}
return deleteFile(snapshot.data().path); // Deletes file
})
.then(success => {
// Worked
})
.catch(error => {
// Error = ApiError: Anonymous caller does not have storage.objects...
})
return; // This statement was creating the problems
}
When I removed the return statement, I no longer got the error. I thought in my case it may have something to do with firebase-admin object instance getting deallocated and re-allocated between asynchronous operations (steps 1 and 2 above), or at least its GCS auth token?
All FCF instances should have access to GCS via a service account that is auto-generated. You can confirm this in the GCP console : https://console.cloud.google.com/iam-admin/serviceaccounts/
From the code snippet you posted I can't see anything that would cause the same issue I was getting, but maybe have a think about any time-based events that could cause this behaviour. That may explain the inconsistent behaviour you elude to.
Hope that's some sort of help.

Categories

Resources