How to get more result using node-youtube getbyId() method - node.js

I am using node-youtube(data api) to get the result of youtube-saerch by id. When I write
res.render('index',{data:(JSON.stringify(result, null, 2))}); then I get two results. But when i write res.render('index',{data:result}); then i get only when result. How can i get more results by simply writing res.render('index',{data:result});
rather than writing
res.render('index',{data:(JSON.stringify(result, null, 2))});
Here is the code of getbyId() metod.
var YouTube = require('youtube-node');
var youTube = new YouTube();
youTube.setKey('*************************');
youTube.getById('HcwTxRuq-uk', function(error, result) {
if (error) {
console.log(error);
}
else {
res.render('index',{data:(JSON.stringify(result, null, 2))});
}
});
I have also tried JSON.parse() method.
like this
var str=(JSON.stringify(result, null, 3));
var data=JSON.parse(str);
In str there are 3 results but in data there is only 1 result. why it return
one result. Also can i get 3 results using JSON.parse().

I hope this is what you want
Also notice there's no need for JSON.stringify at all
var YouTube = require('youtube-node');
var youTube = new YouTube();
youTube.setKey('************************************');
youTube.search('World War z Trailer', 2, function(error, result) {
if (error) {
console.log(error);
} else {
// result should contain 2 videos with some info
// to get more info use getById
var videos = [];
var video1 = result.items[0].id.videoId;
var video2 = result.items[1].id.videoId;
//get 1st video
youTube.getById(video1, function(error, result) {
if (!error) videos.push(result.items[0]);
// get 2nd video
youTube.getById(video2, function(error, result) {
if (!error) videos.push(result.items[0]);
//console.log(videos[0]);
//console.log(videos[1]);
res.render('index',{data:videos)});
});
});
}
});

I know this is not exactly your question, but I think it could help you to see how I'm doing in one of my projects.
If your videos are in a playlist, you can fetch up to 50 videos at the same time and use the pageToken to fetch more if you want more videos from the playlist.
You can fetch the playlist like this :
/**
* Return an array about the videos contained in the GEM-MECHANIC playlist (based on the selected language).
*
* #param $errorMessage String to return the error message.
* #param $language Int language code for which we must fetch the video (default 1 = english)
* #param $maxVideo Int maximum of video we must fetch with the request (<= 0 mean infinite, 5 if invalid)
* #param $playList Int Playlist which want to fetch (Use PlayList class constants).
*
* #return Bidimensionnal Array
*/
static public function getVideoList(&$errorMessage, $language = 1, $maxVideo = 0, $playList = PlayList::GEM_CAR){
$errorMessage = "";
$list = array();
$gemPlayList = self::getPlayList($playList);
if (array_key_exists($language, $gemPlayList)){
if (!is_numeric($maxVideo) or $maxVideo < 0){
$maxVideo = 5;
}
$list = self::fetchVideoList($errorMessage, $gemPlayList[$language], $maxVideo);
}
elseif(empty($gemPlayList)){
$errorMessage = GeneralDbManager::getInstance()->getErrorMessage("GEM_MECHANIC_INVALID_PLAYLIST_ERR", "The selected playlist doesn't exists.");
}
else{
$errorMessage = GeneralDbManager::getInstance()->getErrorMessage("GEM_MECHANIC_INVALID_LANGUAGE_ERR", 'The selected playlist do not contains videos for the language selected.');
}
return $list;
}
/**
* Return an array about the videos contained in the GEM-MECHANIC playlist (based on the selected language).
*
* #param $errorMessage String to return the error message.
* #param $playListId String id of the youtube playlist for which we want to fetch the video list.
* #param $maxVideo Int maximum of video we must fetch with the request
* #param $maxVideo Int number of videos with fetched so far.
* #param $nextToken String to use to fetch more videos.
*
* #return Bidimensionnal Array
*/
private static function fetchVideoList(&$errorMessage, $playListId, $maxVideo, $currentCount = 0, $nextToken = "", $currentList = array()){
if ($currentCount < $maxVideo or $maxVideo === 0) {
$result = abs($maxVideo - $currentCount);
$param = array('playlistId' => $playListId);
if ($result > 50 or $result === 0){
$param['maxResults'] = 50;
$result = 50;
}
else{
$param['maxResults'] = $result;
}
if (!empty($nextToken)){
$param['pageToken'] = $nextToken;
}
try{
$client = new Google_Client();
$client->setDeveloperKey(self::$apiKey);
$youtube = new Google_Service_YouTube($client);
$playList = $youtube->playlistItems->listPlaylistItems('contentDetails, snippet', $param);
unset($youtube);
unset($client);
foreach($playList as $video){
$currentList[] = array('id' => $video['contentDetails']['videoId'], "title" => $video['snippet']['title'], "check" => 0);
}
$currentCount += $result;
if (empty($errorMessage) and !is_null($playList['nextPageToken']) and $currentCount < $maxVideo){
self::fetchVideoList($errorMessage, $language, $maxVideo, $currentCount, $playList['nextPageToken'], $currentList);
}
unset($playList);
}
catch (Google_Exception $exception) {
ExceptionLogger::logException($exception);
$errorMessage = GeneralDbManager::getInstance()->getErrorMessage("GEM_MECHANIC_CANT_FETCH_VIDEO_ERR", 'We are currently not able to fetch the video list from Youtube.');
}
}
return $currentList;
}

Related

Javascript Audio Streaming via Audio Worklet Float 32 Array convert to audio file

I am using AudioWorkletProcessor, I need to store all the audio stream data into a single file and play it at the end.
Below is my AudioWorkletProcessor code:
class RecorderProcessor extends AudioWorkletProcessor {
// 0. Determine the buffer size (this is the same as the 1st argument of ScriptProcessor)
//bufferSize = 4096
bufferSize = 256
// 1. Track the current buffer fill level
_bytesWritten = 0
// 2. Create a buffer of fixed size
_buffer = new Float32Array(this.bufferSize)
constructor() {
super(); // exception thrown here when not called
this.initBuffer()
}
initBuffer() {
this._bytesWritten = 0
}
isBufferEmpty() {
return this._bytesWritten === 0
}
isBufferFull() {
return this._bytesWritten === this.bufferSize
}
/**
* #param {Float32Array[][]} inputs
* #returns {boolean}
*/
process(inputs) {
// Grabbing the 1st channel similar to ScriptProcessorNode
this.append(inputs[0][0])
// this.append(outputs[0][0])
return true
}
/**
*
* #param {Float32Array} channelData
*/
append(channelData) {
if (this.isBufferFull()) {
this.flush()
}
if (!channelData) return
for (let i = 0; i < channelData.length; i++) {
this._buffer[this._bytesWritten++] = channelData[i]
}
}
flush() {
// trim the buffer if ended prematurely
this.port.postMessage(
this._bytesWritten < this.bufferSize
? this._buffer.slice(0, this._bytesWritten)
: this._buffer
)
this.initBuffer()
}
}
registerProcessor("recorderWorkletProcessor", RecorderProcessor)
which returning 32 bit Float array .
Below is my javascript code :
var recordingNode; //audio worklet node
var micSourceNode; //mic node
const chunks = []; // storing all stream audio chunks
try {
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
microphone = navigator.getUserMedia({
audio: true,
video: false
}, onMicrophoneGranted, onMicrophoneDenied);
} catch (e) {
alert(e)
}
function onMicrophoneDenied() {
console.log('denied')
}
async function onMicrophoneGranted(stream) {
context = new AudioContext({
sampleRate: 48000
});
micSourceNode = context.createMediaStreamSource(stream);
await context.audioWorklet.addModule('/app_resources/recorderWorkletProcessor.js');
recordingNode = new AudioWorkletNode(context, "recorderWorkletProcessor")
recordingNode.port.onmessage = function(e) {
chunks.push(e.data); //storing chunks in arrau
}
micSourceNode
.connect(recordingNode)
.connect(context.destination);
}
function stopstream() {
if (micSourceNode)
micSourceNode.disconnect(recordingNode);
var blob = new Blob(chunks, {
type: "audio/webm;codecs=opus"
});
console.log(blob.size)
const audioUrl = URL.createObjectURL(blob);
document.getElementById('song').innerHTML = '<audio id="audio-player" controls="controls" src="' + audioUrl + '" type="audio/mpeg">';
}
I am unable to convert the float 32 bit array into audio file. i can see the size in the blob but unable to play audio. Please help me understand what can i do here to make it work.

Chrome.tabs.sendMessage is not sending a message to content script

I have looked at a lot of different posts about using execute script and send message to execute the content script on a specified tab, but it doesn't execute the content script until I do a hard refresh and then the response from the content script is successful. Attached below is the call back function for button clicked this is in a popup.js file.
function buttonClicked() {
// Get an object for the active tab
console.log("print dymo has been clicked");
chrome.tabs.query({active: true, currentWindow: true}, function(tab_array){
// send a messege to the contentscript that will then scrape the web
// it will then call the popup.js receiveURL() method with the url it makes
console.log("Messege sent to conntent script");
alert("print has been clicked")
alert(tab_array[0].id)
chrome.tabs.sendMessage(tab_array[0].id, {getHTML: true}, receiveURL);
});
Content Script:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// When there is a request (that will come in as true)
if (request) {
/*********************************************************************
IF YOU NEED TO CHANGE THE WEB SCRAPER START HERE
**********************************************************************/
// Take out everything in the html before the tag "<label>Job:</label>"
// Selects only the inner elements between the style row
var matches = document.querySelectorAll('ul.list-unstyled')
//Gives us the inner text of the elements of information
//Gives us an array of all the information split up by new lines
information = matches[1].innerText.split(/\r?\n/)
//Iterate ansd store everything in a dictionary split by a :
var dict_info = {}
for (index = 0; index < information.length; index++) {
parts = information[index].split(": ")
ans = ""
for(i = 1; i < parts.length; i++) {
ans += parts[i]
}
dict_info[parts[0]] = ans
}
var name = dict_info['Requestor']
var job = dict_info['Job']
if (job != undefined) {
job = job.match(JOB_REGEX)[1]
}
var request = dict_info['Request']
if (request != undefined) {
request = request.match(REQ_REGEX)[1]
}
var file = dict_info["File"]
if (file.length > 10) {
file = file.substring(0,file.length-9)
}
if (file.length > 20) {
file = file.substring(0, 20)
}
var email = dict_info['Requestor Email']
var cost = dict_info['Estimated Cost']
if(cost == undefined) {
cost = dict_info['Cost']
}
if (cost != undefined) {
cost = cost.match(COST_REGEX)[1]
}
name = name.split(" ")
name = name[0] + "/" + name[name.length-1]
var url = "https:// test"
sendResponse(url);
return true;
}
}
);

Update link to heading in google docs

In google docs one can easily add headings and link to them from inside of the document. But when the heading text changes, the link text does not change.
Is there a way to change that behavior or update the link text automatically?
I know it is about 1 1/2 years, but maybe this will help. I have had the exact same problem and wrote a function that will update all the links to the headings in a document. Since I could not find any built-in functions or add-ons, the only way was to script it.
Some things to consider:
This needs a current table of contents to work. If you don't have (or do not want) a TOC, you can insert one, run that function and delete it afterwards. Also, I have only tested it with a TOC that contains page numbers.
It will update ALL texts of links to headings in the document. However, links to everything else remain untouched.
Please use at your own risk (maybe try it out in a copy of your document). I have tested it, but the testing could have been more thorough. Also, this is my first in scripting Docs.
Paste this in the Script editor of your doc and run replaceHeadingLinks. Links that the script could not update (because they link to a heading that does not exist anymore) will be output in the console.
function replaceHeadingLinks() {
var curDoc = DocumentApp.getActiveDocument();
var links = getAllLinks_(curDoc.getBody());
var headings = getAllHeadings_(curDoc.getBody());
var deprecatedLinks = []; // holds all links to headings that do not exist anymore.
links.forEach(function(link) {
if(link.url.startsWith('#heading')) {
// get the new heading text
var newHeadingText = headings.get(link.url);
// if the link does not exist anymore, we cannot update it.
if(typeof newHeadingText !== "undefined") {
var newOffset = link.startOffset + newHeadingText.length - 1;
// delete the old text, insert new one and set link
link.element.deleteText(link.startOffset, link.endOffsetInclusive);
link.element.insertText(link.startOffset, newHeadingText);
link.element.setLinkUrl(link.startOffset, newOffset, link.url);
} else {
deprecatedLinks.push(link);
}
}
}
)
// error handling: show deprecated links:
if(deprecatedLinks.length > 0) {
Logger.log("Links we could not update:");
for(var i = 0; i < deprecatedLinks.length; i++) {
var link = deprecatedLinks[i];
var oldText = link.element.getText().substring(link.startOffset, link.endOffsetInclusive);
Logger.log("heading: " + link.url + " / description: " + oldText);
}
} else {
Logger.log("all links updated");
}
}
/**
* Get an array of all LinkUrls in the document. The function is
* recursive, and if no element is provided, it will default to
* the active document's Body element.
*
* #param {Element} element The document element to operate on.
* .
* #returns {Array} Array of objects, vis
* {element,
* startOffset,
* endOffsetInclusive,
* url}
*
* Credits: https://stackoverflow.com/questions/18727341/get-all-links-in-a-document/40730088
*/
function getAllLinks_(element) {
var links = [];
element = element || DocumentApp.getActiveDocument().getBody();
if (element.getType() === DocumentApp.ElementType.TEXT) {
var textObj = element.editAsText();
var text = element.getText();
var inUrl = false;
var curUrl = {};
for (var ch=0; ch < text.length; ch++) {
var url = textObj.getLinkUrl(ch);
if (url != null) {
if (!inUrl) {
// We are now!
inUrl = true;
curUrl = {};
curUrl.element = element;
curUrl.url = String( url ); // grab a copy
curUrl.startOffset = ch;
}
else {
curUrl.endOffsetInclusive = ch;
}
}
else {
if (inUrl) {
// Not any more, we're not.
inUrl = false;
links.push(curUrl); // add to links
curUrl = {};
}
}
}
// edge case: link is at the end of a paragraph
// check if object is empty
if(inUrl && (Object.keys(curUrl).length !== 0 || curUrl.constructor !== Object)) {
links.push(curUrl); // add to links
curUrl = {};
}
}
else {
// only traverse if the element is traversable
if(typeof element.getNumChildren !== "undefined") {
var numChildren = element.getNumChildren();
for (var i=0; i<numChildren; i++) {
// exclude Table of Contents
child = element.getChild(i);
if(child.getType() !== DocumentApp.ElementType.TABLE_OF_CONTENTS) {
links = links.concat(getAllLinks_(element.getChild(i)));
}
}
}
}
return links;
}
/**
* returns a map of all headings within an element. The map key
* is the heading ID, such as h.q1xuchg2smrk
*
* THIS REQUIRES A CURRENT TABLE OF CONTENTS IN THE DOCUMENT TO WORK PROPERLY.
*
* #param {Element} element The document element to operate on.
* .
* #returns {Map} Map with heading ID as key and the heading element as value.
*/
function getAllHeadings_(element) {
var headingsMap = new Map();
var p = element.findElement(DocumentApp.ElementType.TABLE_OF_CONTENTS).getElement();
if(p !== null) {
var toc = p.asTableOfContents();
for (var ti = 0; ti < toc.getNumChildren(); ti++) {
var itemToc = toc.getChild(ti).asParagraph().getChild(0).asText();
var itemText = itemToc.getText();
var itemUrl = itemToc.getLinkUrl(0);
var itemDesc = null;
// strip the line numbers if TOC contains line numbers
var itemText = itemText.match(/(.*)\t/)[1];
headingsMap.set(itemUrl,itemText);
}
}
return headingsMap;
}

find returns the required data but $match doesn't in mongodb

I am trying to get required data using $match but it is returning null every time. On the other hand find returns the required data. I have to implement $lookup and $merge on the result I get but $match results null.
I have tried using a basic query in $match but it still returns null. I tried other posts too but in every post the steps that are given are not to my satisfaction.
This is my code:
var posts;
var area = "addresses."
var range = area.concat(req.body.range);
var place = req.body.place;
var reg = new RegExp(place, "i");
var query = {};
query[range] = reg;
/*Posts.find(query)*/ // this returns the result
Posts.aggregate( // inside this I get posts not found and
// the console.log prints empty value
[
{$match: {query}}
],
function(err, posts) {
if (err) {
return res.send(err).end;
} else if(posts.length > 0){
console.log("posts = "+posts);
reply[Constant.REPLY.MESSAGE] = "post by user found";
reply[Constant.REPLY.DATA] = posts;
reply[Constant.REPLY.RESULT_CODE] = 200;
reply[Constant.REPLY.TOKEN] = "";
return res.send(reply).end;
}else {
console.log("posts = "+posts); //empty value
reply[Constant.REPLY.MESSAGE] = "posts not found";
reply[Constant.REPLY.DATA] = null;
reply[Constant.REPLY.RESULT_CODE] = 200;
reply[Constant.REPLY.TOKEN] = "";
return res.send(reply).end;
}
}
);
The result of both find and $match must be same.

node.js object inheritance overwriting object methods

I am trying to port a Java application for use in node.js, and am running into an issue with Object inheritance. I have a base object HVal, and 2 subclasses, HBin and HBool. When I try to use both HBin and HBool, the 1st object that is loaded is overridden by the 2nd object that is loaded, even though they are being assigned to different vars. Anyone have an idea of what is going on here.
HVal.js
/** Package private constructor */
function HVal() {};
/** Abstract functions that must be defined in inheriting classes
* hashCode: int - Hash code is value based
* toZinc: String - Encode value to zinc format
* equals: boolean - Equality is value based
*/
/** String - String format is for human consumption only */
HVal.prototype.toString = function() { return this.toZinc(); };
/** int - Return sort order as negative, 0, or positive */
HVal.prototype.compareTo = function(that) { return this.toString().localeCompare(that); };
/** boolean - check for type match */
HVal.prototype.typeis = function (check, prim, obj) { return typeof(check)==prim || check instanceof obj; };
/** Add hashCode function to Javascript String object */
String.prototype.hashCode = function() {
var hash = 0, i, chr, len;
if (this.length == 0) return hash;
for (i = 0, len = this.length; i < len; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
/** Export for use in other modules */
module.exports = new HVal();
HBin.js
var hval = require('./HVal');
/** Private constructor */
function HBin(mime) {
/** MIME type for binary file */
this.mime = mime;
};
HBin.prototype = hval;
/** Construct for MIME type */
HBin.prototype.make = function(mime) {
if (!hval.typeis(mime, 'string', String) || mime.length == 0 || mime.indexOf('/') < 0)
throw new Error("Invalid mime val: \"" + mime + "\"");
return new HBin(mime);
};
/** int - Hash code is based on mime field */
HBin.prototype.hashCode = function() { return mime.hashCode(); };
/** String - Encode as "Bin(<mime>)" */
HBin.prototype.toZinc = function() {
var s = "Bin(";
for (var i=0; i<this.mime.length; ++i)
{
var c = this.mime.charAt(i);
if (c > 127 || c == ')') throw new Error("Invalid mime, char='" + c + "'");
s += c;
}
s += ")";
return s.toString();
};
/** boolean - Equals is based on mime field */
HBin.prototype.equals = function(that) {
if (!typeOf(that) == HBin) return false;
return this.mime === that.mime;
};
/** Export for use in other modules */
module.exports = new HBin();
HBool.js
var hval = require('./HVal');
/** Private constructor */
function HBool(val) {
/** Boolean value */
this.val = val;
};
HBool.prototype = hval;
/** Construct from boolean value */
HBool.prototype.make = function(val) {
if (!hval.typeis(val, 'boolean', Boolean))
throw new Error("Invalid boolean val: \"" + val + "\"");
return new HBool(val);
};
/** int - Hash code is same as java.lang.Boolean */
HBool.prototype.hashCode = function() { return this.val ? 1231 : 1237; };
/** String - Encode as T/F */
HBool.prototype.toZinc = function() { return this.val ? "T" : "F"; };
/** boolean - Equals is based on reference */
HBool.prototype.equals = function(that) { return this === that; };
/** String - String format is for human consumption only */
HBool.prototype.toString = function() { return this.val ? "true" : "false"; };
/** Export for use in other modules */
module.exports = new HBool();
index.js
var hbin = require('./HBin');
var hbool = require('./HBool');
console.log('BIN: ' + hbin.make("test/test").toString());
console.log();
console.log('T: ' + hbool.make(true).toString());
console.log('F: ' + hbool.make(false).toString());
Output - failing on first console.log
HBool.js:19
throw new Error("Invalid boolean val: \"" + val + "\"");
Error: Invalid boolean val: "test/test"
at HVal.HBool.make (HBool.js:19:11)
at Object.<anonymous> (index.js:4:28)
...
The issue has to do with how you're exporting from a module and how you're assigning the prototype when you want to inherit and the issue is subtle. There are a couple things going on here. First off, module.exports is cached for modules, so every time you do:
var hval = require('./HVal');
you are getting the exact same HVal instantiated object back each time and you can never make a different object because you didn't export the constructor. That is a problem for all your modules. You should export the constructor function and let the user of the module actually create new instances of your object with new.
You can do that by changing:
module.exports = new HVal();
to:
module.exports = HVal;
And, then when you require() it, you just get the constructor:
var HVal = require('./HVal');
var HBool = require('./HBool');
And, then you can create an HBool object like this:
var hbool = new HBool();
This issue then seems to be messing up your inheritance when you assign something like:
HBool.prototype = hval;
The problem is entirely fixed if you export the constructors themselves and then change the above prototype assignment to use Object.create:
HBool.prototype = Object.create(HVal.prototype);
You can see a working demo here (modules removed to make the demo easier to show): http://jsfiddle.net/jfriend00/ty5wpkqm/
I also made another correction to the code. Instead of this:
if (!hval.typeis(mime, 'string', String) || mime.length == 0 || mime.indexOf('/') < 0)
I changed it to actually use the inherited methods on this object:
if (!this.typeis(mime, 'string', String) || mime.length == 0 || mime.indexOf('/') < 0)
This is the proper way to call methods on the current object (even inherited methods). Now, this happens to be a static method (it doesn't use the instance at all so you could move it off the object entirely, but since you have declared it on the object, you should refer to it as this.typeis().
I also noticed that your .equals() method is not correct. You have this:
/** boolean - Equals is based on mime field */
HBin.prototype.equals = function(that) {
if (!typeOf(that) == HBin) return false;
return this.mime === that.mime;
};
First off, did you create a new global function called typeOf()? The built-in mechanism in Javascript is lowercase typeof. Second off, typeof(that) will never be HBin. Objects in Javascript don't report a type like that. An object would report typeof(that) === "object". You can perhaps use instanceof:
/** boolean - Equals is based on mime field */
HBin.prototype.equals = function(that) {
return that instanceof HBin && this.mime === that.mime;
};

Resources