openvibers/openvibe.live Commits
Moment titles from a scene note: no "The streamer is", no dangling end (#603)
Changes
@@@ -60,9 +60,12 @@ function _deJson(desc) {}// The title when the AI gives none. A frame caption's first clause, when it reads as a title: never cut off on a// dangling word ("…Speaking To"). Otherwise the stream's own title and the moment's time ("Fortnite! at 41:20").--const DANGLING = /\s+(to|in|with|a|an|of|and|the|on|at|is|are|was|from|for|by|near|while|as|or|into|onto|its|his|her|their)$/i;++const DANGLING = /\s+(to|in|with|a|an|of|and|the|on|at|is|are|was|from|for|by|near|while|as|or|into|onto|its|his|her|their|inside|outside|behind|under|over|through|toward|towards|around|about|like|that|which|who|where|when|what|[\w-]+-like)$/i;++// "The streamer is playing …": on a streaming site the subject says nothing, and it took three of a title's nine words++// (11-03 home: "The Streamer Is Livestreaming From A Low-Angle POV Inside").++const STREAMER_IS = /^the (?:streamer|broadcaster|host) (?:is|was) (?=\w+ing\b)/i;function _captionTitle(desc) {-- let s = _cleanText(desc).split(/[.!?;:]|,\s(?=(?:with|and|as|while|near|showing|likely)\b)/i)[0].trim();++ let s = _cleanText(desc).split(/[.!?;:]|,\s(?=(?:with|and|as|while|near|showing|likely)\b)/i)[0].trim().replace(STREAMER_IS, '');s = s.split(' ').filter(Boolean).slice(0, 9).join(' ').replace(/[,\s]+$/, '');while (DANGLING.test(s)) s = s.replace(DANGLING, '');if (s.split(' ').length < 3) return null;@@@ -18,6 +18,11 @@ assert.strictEqual(captionTitle('A person is assembling a small robotic device o// Describing people is fine: a caption about someone is a title like any other.assert.strictEqual(captionTitle('A man with a beard is speaking to the camera.'), 'A Man With A Beard Is Speaking');assert.strictEqual(captionTitle('A young boy plays a game.'), 'A Young Boy Plays A Game');++// 11-03: "The streamer is …-ing" gives its words to the moment, and a title never ends on a word that leads on.++assert.strictEqual(captionTitle('The streamer is playing Fortnite, sprinting through a cave-like tunnel with a shotgun.'), 'Playing Fortnite, Sprinting Through A Cave-Like Tunnel');++assert.strictEqual(captionTitle('The streamer is livestreaming from a low-angle POV inside a parked car at night.'), 'Livestreaming From A Low-Angle POV Inside A Parked Car');++assert.strictEqual(captionTitle('The streamer sits in a red chair and waves.'), 'The Streamer Sits In A Red Chair And Waves', 'only "is …-ing" is dropped');++assert.strictEqual(captionTitle('A dog runs through a long hallway behind the couch.'), 'A Dog Runs Through A Long Hallway', 'nine words, then every dangling word goes');const vod = { title: 'Fortnite!' };assert.strictEqual(fallbackTitle(vod, 2480, 'A man wearing a headset sits in a gaming chair.'), 'A Man Wearing A Headset Sits In A Gaming', 'nine words at most');assert.strictEqual(fallbackTitle(vod, 2480, 'The Minecraft main menu is displayed with a panorama.'), 'The Minecraft Main Menu Is Displayed With A Panorama', 'a complete clause is kept whole');
@@ -60,9 +60,12 @@ function _deJson(desc) {
@@ -60,9 +60,12 @@ function _deJson(desc) {
}
}
// The title when the AI gives none. A frame caption's first clause, when it reads as a title: never cut off on a
// The title when the AI gives none. A frame caption's first clause, when it reads as a title: never cut off on a
// dangling word ("…Speaking To"). Otherwise the stream's own title and the moment's time ("Fortnite! at 41:20").
// dangling word ("…Speaking To"). Otherwise the stream's own title and the moment's time ("Fortnite! at 41:20").
-const DANGLING = /\s+(to|in|with|a|an|of|and|the|on|at|is|are|was|from|for|by|near|while|as|or|into|onto|its|his|her|their)$/i;
+const DANGLING = /\s+(to|in|with|a|an|of|and|the|on|at|is|are|was|from|for|by|near|while|as|or|into|onto|its|his|her|their|inside|outside|behind|under|over|through|toward|towards|around|about|like|that|which|who|where|when|what|[\w-]+-like)$/i;
+// "The streamer is playing …": on a streaming site the subject says nothing, and it took three of a title's nine words
+// (11-03 home: "The Streamer Is Livestreaming From A Low-Angle POV Inside").
+const STREAMER_IS = /^the (?:streamer|broadcaster|host) (?:is|was) (?=\w+ing\b)/i;
function _captionTitle(desc) {
function _captionTitle(desc) {
- let s = _cleanText(desc).split(/[.!?;:]|,\s(?=(?:with|and|as|while|near|showing|likely)\b)/i)[0].trim();
+ let s = _cleanText(desc).split(/[.!?;:]|,\s(?=(?:with|and|as|while|near|showing|likely)\b)/i)[0].trim().replace(STREAMER_IS, '');
s = s.split(' ').filter(Boolean).slice(0, 9).join(' ').replace(/[,\s]+$/, '');
s = s.split(' ').filter(Boolean).slice(0, 9).join(' ').replace(/[,\s]+$/, '');
while (DANGLING.test(s)) s = s.replace(DANGLING, '');
while (DANGLING.test(s)) s = s.replace(DANGLING, '');
if (s.split(' ').length < 3) return null;
if (s.split(' ').length < 3) return null;
@@ -18,6 +18,11 @@ assert.strictEqual(captionTitle('A person is assembling a small robotic device o
@@ -18,6 +18,11 @@ assert.strictEqual(captionTitle('A person is assembling a small robotic device o
// Describing people is fine: a caption about someone is a title like any other.
// Describing people is fine: a caption about someone is a title like any other.
assert.strictEqual(captionTitle('A man with a beard is speaking to the camera.'), 'A Man With A Beard Is Speaking');
assert.strictEqual(captionTitle('A man with a beard is speaking to the camera.'), 'A Man With A Beard Is Speaking');
assert.strictEqual(captionTitle('A young boy plays a game.'), 'A Young Boy Plays A Game');
assert.strictEqual(captionTitle('A young boy plays a game.'), 'A Young Boy Plays A Game');
+// 11-03: "The streamer is …-ing" gives its words to the moment, and a title never ends on a word that leads on.
+assert.strictEqual(captionTitle('The streamer is playing Fortnite, sprinting through a cave-like tunnel with a shotgun.'), 'Playing Fortnite, Sprinting Through A Cave-Like Tunnel');
+assert.strictEqual(captionTitle('The streamer is livestreaming from a low-angle POV inside a parked car at night.'), 'Livestreaming From A Low-Angle POV Inside A Parked Car');
+assert.strictEqual(captionTitle('The streamer sits in a red chair and waves.'), 'The Streamer Sits In A Red Chair And Waves', 'only "is …-ing" is dropped');
+assert.strictEqual(captionTitle('A dog runs through a long hallway behind the couch.'), 'A Dog Runs Through A Long Hallway', 'nine words, then every dangling word goes');
const vod = { title: 'Fortnite!' };
const vod = { title: 'Fortnite!' };
assert.strictEqual(fallbackTitle(vod, 2480, 'A man wearing a headset sits in a gaming chair.'), 'A Man Wearing A Headset Sits In A Gaming', 'nine words at most');
assert.strictEqual(fallbackTitle(vod, 2480, 'A man wearing a headset sits in a gaming chair.'), 'A Man Wearing A Headset Sits In A Gaming', 'nine words at most');
assert.strictEqual(fallbackTitle(vod, 2480, 'The Minecraft main menu is displayed with a panorama.'), 'The Minecraft Main Menu Is Displayed With A Panorama', 'a complete clause is kept whole');
assert.strictEqual(fallbackTitle(vod, 2480, 'The Minecraft main menu is displayed with a panorama.'), 'The Minecraft Main Menu Is Displayed With A Panorama', 'a complete clause is kept whole');