tagradio + mixcloud (fun with subtitles)
commit
7053a5bbd4
@ -0,0 +1 @@
|
||||
*.mp3
|
@ -0,0 +1,6 @@
|
||||
# vosk can also output JSON that includes the timing of each individual
|
||||
# detected WORD!
|
||||
# NOTE: I had an error when I did this and needed to PATCH some PYTHON code in VOSK
|
||||
# see VOSKPATCH.TXT
|
||||
vosk-transcriber -l en-us -i worm25_mia_60.wav -t json -o worm25_mia_60.json
|
||||
|
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
import argparse
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
ap = argparse.ArgumentParser("convert srt into vtt")
|
||||
ap.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
|
||||
ap.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
|
||||
args = ap.parse_args()
|
||||
|
||||
print ("WEBVTT\n", file=args.outfile)
|
||||
for line in args.infile:
|
||||
print (re.sub(r"(\d\d:\d\d:\d\d),(\d\d\d) --> (\d\d:\d\d:\d\d),(\d\d\d)", r"\1.\2 --> \3.\4", line.rstrip()), file=args.outfile)
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<video src="w25mia60.mp3" controls style="width: 100%; height: 320px;">
|
||||
<track default kind="captions" label="vosk" src="w25mia60.vtt"></track>
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<audio src="w25mia60.mp3" controls style="width: 100%">
|
||||
<track default id="captions" kind="metadata" label="vosk" src="w25mia60.vtt"></track>
|
||||
</audio>
|
||||
|
||||
<div id="caption" style="text-align: center; padding: 25px; font-size: 42px; color: line">caption here</div>
|
||||
|
||||
<script>
|
||||
let captrack = document.querySelector("track#captions");
|
||||
let capdiv = document.querySelector("#caption");
|
||||
captrack.addEventListener("cuechange", (e) => {
|
||||
console.log('track: cuechange', e);
|
||||
let text = captrack.track.activeCues[0]?.text || "";
|
||||
console.log(text);
|
||||
capdiv.innerHTML = text;
|
||||
});
|
||||
captrack.track.mode = "hidden";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,110 @@
|
||||
WEBVTT
|
||||
|
||||
1
|
||||
00:00:00.075 --> 00:00:02.610
|
||||
have a particular connection to worms inner
|
||||
|
||||
2
|
||||
00:00:02.610 --> 00:00:05.970
|
||||
and outer workings i wanted to make
|
||||
|
||||
3
|
||||
00:00:05.970 --> 00:00:08.640
|
||||
the series because one has become over
|
||||
|
||||
4
|
||||
00:00:08.640 --> 00:00:10.710
|
||||
twenty five years and institution
|
||||
|
||||
5
|
||||
00:00:11.460 --> 00:00:14.130
|
||||
but an institution built with and for
|
||||
|
||||
6
|
||||
00:00:14.130 --> 00:00:16.110
|
||||
and from a d i y spirits
|
||||
|
||||
7
|
||||
00:00:16.590 --> 00:00:19.080
|
||||
and something that it still retains it's
|
||||
|
||||
8
|
||||
00:00:19.080 --> 00:00:20.490
|
||||
the nature of do i was spaces
|
||||
|
||||
9
|
||||
00:00:20.490 --> 00:00:22.710
|
||||
of course and any cultural spaces that
|
||||
|
||||
10
|
||||
00:00:22.710 --> 00:00:24.390
|
||||
people who make it come and go
|
||||
|
||||
11
|
||||
00:00:24.570 --> 00:00:25.830
|
||||
the name on the building stays the
|
||||
|
||||
12
|
||||
00:00:25.830 --> 00:00:28.260
|
||||
same but the vibe changes and the
|
||||
|
||||
13
|
||||
00:00:28.260 --> 00:00:29.880
|
||||
sense of identity shifts
|
||||
|
||||
14
|
||||
00:00:31.020 --> 00:00:33.000
|
||||
worm is a place of invention and
|
||||
|
||||
15
|
||||
00:00:33.000 --> 00:00:35.880
|
||||
reinvention and with the constant motion certain
|
||||
|
||||
16
|
||||
00:00:35.880 --> 00:00:39.120
|
||||
stories and memories do fade away sometimes
|
||||
|
||||
17
|
||||
00:00:39.120 --> 00:00:39.870
|
||||
quite quickly
|
||||
|
||||
18
|
||||
00:00:40.770 --> 00:00:42.563
|
||||
the idea of this history of why
|
||||
|
||||
19
|
||||
00:00:42.563 --> 00:00:44.790
|
||||
i'm not the only possible history of
|
||||
|
||||
20
|
||||
00:00:44.790 --> 00:00:47.160
|
||||
course is to try and capture a
|
||||
|
||||
21
|
||||
00:00:47.160 --> 00:00:48.750
|
||||
few of those stories with the people
|
||||
|
||||
22
|
||||
00:00:48.750 --> 00:00:50.748
|
||||
that i've met and people that maria
|
||||
|
||||
23
|
||||
00:00:50.748 --> 00:00:52.680
|
||||
it has known along the way
|
||||
|
||||
24
|
||||
00:00:53.790 --> 00:00:54.780
|
||||
but i'm not going to begin at
|
||||
|
||||
25
|
||||
00:00:54.780 --> 00:00:56.880
|
||||
the beginning that would be logical but
|
||||
|
||||
26
|
||||
00:00:56.880 --> 00:00:59.370
|
||||
actually have already begun obviously and today's
|
||||
|
||||
27
|
||||
00:00:59.370 --> 00:00:59.970
|
||||
episode
|
||||
|
@ -0,0 +1,132 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['exports', 'module'], factory);
|
||||
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
|
||||
factory(exports, module);
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(mod.exports, mod);
|
||||
global.fetchJsonp = mod.exports;
|
||||
}
|
||||
})(this, function (exports, module) {
|
||||
'use strict';
|
||||
|
||||
var defaultOptions = {
|
||||
timeout: 5000,
|
||||
jsonpCallback: 'callback',
|
||||
jsonpCallbackFunction: null
|
||||
};
|
||||
|
||||
function generateCallbackFunction() {
|
||||
return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
|
||||
}
|
||||
|
||||
function clearFunction(functionName) {
|
||||
// IE8 throws an exception when you try to delete a property on window
|
||||
// http://stackoverflow.com/a/1824228/751089
|
||||
try {
|
||||
delete window[functionName];
|
||||
} catch (e) {
|
||||
window[functionName] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function removeScript(scriptId) {
|
||||
var script = document.getElementById(scriptId);
|
||||
if (script) {
|
||||
document.getElementsByTagName('head')[0].removeChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchJsonp(_url) {
|
||||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
||||
|
||||
// to avoid param reassign
|
||||
var url = _url;
|
||||
var timeout = options.timeout || defaultOptions.timeout;
|
||||
var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
|
||||
|
||||
var timeoutId = undefined;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
|
||||
var scriptId = jsonpCallback + '_' + callbackFunction;
|
||||
|
||||
window[callbackFunction] = function (response) {
|
||||
resolve({
|
||||
ok: true,
|
||||
// keep consistent with fetch API
|
||||
json: function json() {
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
});
|
||||
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
|
||||
removeScript(scriptId);
|
||||
|
||||
clearFunction(callbackFunction);
|
||||
};
|
||||
|
||||
// Check if the user set their own params, and if not add a ? to start a list of params
|
||||
url += url.indexOf('?') === -1 ? '?' : '&';
|
||||
|
||||
var jsonpScript = document.createElement('script');
|
||||
jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction);
|
||||
if (options.charset) {
|
||||
jsonpScript.setAttribute('charset', options.charset);
|
||||
}
|
||||
if (options.nonce) {
|
||||
jsonpScript.setAttribute('nonce', options.nonce);
|
||||
}
|
||||
if (options.referrerPolicy) {
|
||||
jsonpScript.setAttribute('referrerPolicy', options.referrerPolicy);
|
||||
}
|
||||
if (options.crossorigin) {
|
||||
jsonpScript.setAttribute('crossorigin', 'true');
|
||||
}
|
||||
jsonpScript.id = scriptId;
|
||||
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
|
||||
|
||||
timeoutId = setTimeout(function () {
|
||||
reject(new Error('JSONP request to ' + _url + ' timed out'));
|
||||
|
||||
clearFunction(callbackFunction);
|
||||
removeScript(scriptId);
|
||||
window[callbackFunction] = function () {
|
||||
clearFunction(callbackFunction);
|
||||
};
|
||||
}, timeout);
|
||||
|
||||
// Caught if got 404/500
|
||||
jsonpScript.onerror = function () {
|
||||
reject(new Error('JSONP request to ' + _url + ' failed'));
|
||||
|
||||
clearFunction(callbackFunction);
|
||||
removeScript(scriptId);
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// export as global function
|
||||
/*
|
||||
let local;
|
||||
if (typeof global !== 'undefined') {
|
||||
local = global;
|
||||
} else if (typeof self !== 'undefined') {
|
||||
local = self;
|
||||
} else {
|
||||
try {
|
||||
local = Function('return this')();
|
||||
} catch (e) {
|
||||
throw new Error('polyfill failed because global object is unavailable in this environment');
|
||||
}
|
||||
}
|
||||
local.fetchJsonp = fetchJsonp;
|
||||
*/
|
||||
|
||||
module.exports = fetchJsonp;
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>minimal archive.org search</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This is a minimal form to send a search request to archive.org</p>
|
||||
<form action="https://archive.org/advancedsearch.php">
|
||||
<input size="50" type="text" name="q" value="subject:"field recording"">
|
||||
<input type="submit" value="Search">
|
||||
<!-- the rest are hidden -->
|
||||
<input type="hidden" name="fl[]" value="date">
|
||||
<input type="hidden" name="fl[]" value="description">
|
||||
<input type="hidden" name="fl[]" value="format">
|
||||
<input type="hidden" name="fl[]" value="identifier">
|
||||
<input type="hidden" name="fl[]" value="licenseurl">
|
||||
<input type="hidden" name="fl[]" value="mediatype">
|
||||
<input type="hidden" name="fl[]" value="name">
|
||||
<input type="hidden" name="fl[]" value="rights">
|
||||
<input type="hidden" name="fl[]" value="subject">
|
||||
<input type="hidden" name="fl[]" value="title">
|
||||
<input type="hidden" name="fl[]" value="type">
|
||||
<input type="hidden" name="sort[]" value="year desc">
|
||||
<input type="hidden" name="sort[]" value="identifier asc">
|
||||
<input id="numresults" type="hidden" name="rows" value="10">
|
||||
<input type="hidden" name="page" value="1">
|
||||
<input type="hidden" name="output" value="json">
|
||||
<!-- <input type="hidden" name="output" value="tables">
|
||||
<input type="hidden" name="callback" value="callback"> -->
|
||||
</form>
|
||||
<div id="results"></div>
|
||||
<script src="fetch-jsonp.js"></script>
|
||||
<script src="tagradio.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
// https://github.com/camsong/fetch-jsonp
|
||||
// https://raw.githubusercontent.com/camsong/fetch-jsonp/refs/heads/master/src/fetch-jsonp.js
|
||||
|
||||
let form = document.querySelector("form");
|
||||
|
||||
form.addEventListener("submit", event => {
|
||||
// console.log("GO NO FURTHER FORM... I'll take it from here");
|
||||
event.preventDefault();
|
||||
let formdata = new FormData(form);
|
||||
let usp = new URLSearchParams(formdata);
|
||||
console.log("urlsearchparams", usp.toString());
|
||||
let results_div = document.querySelector("#results");
|
||||
fetchJsonp("https://archive.org/advancedsearch.php?"+usp.toString())
|
||||
.then(resp => resp.json())
|
||||
.then(data => {
|
||||
console.log("data", data);
|
||||
data.response.docs.forEach (doc => {
|
||||
console.log(doc);
|
||||
let div = document.createElement("div");
|
||||
let a = document.createElement("a");
|
||||
let item_url = `https://archive.org/details/${doc.identifier}`;
|
||||
let item_metadata_url = `https://archive.org/metadata/${doc.identifier}`;
|
||||
a.href = item_url;
|
||||
a.textContent = doc.title;
|
||||
div.appendChild(a);
|
||||
results_div.appendChild(div);
|
||||
|
||||
fetchJsonp(item_metadata_url)
|
||||
.then (resp => resp.json())
|
||||
.then(item_data => {
|
||||
console.log("*", item_data);
|
||||
let file_url = `https://${item_data.server}${item_data.dir}/`;
|
||||
let mp3_files = item_data.files.filter(f => f.format == "VBR MP3");
|
||||
let first_file_url = file_url + encodeURI(mp3_files[0].name);
|
||||
let audio = document.createElement("audio");
|
||||
div.appendChild(audio);
|
||||
audio.controls = true;
|
||||
audio.src = first_file_url;
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
// here we have access to the response data...
|
||||
})
|
||||
|
||||
// fetch("https://archive.org/advancedsearch.php", {
|
||||
// method: "cors",
|
||||
// body: formdata
|
||||
// }).then(resp => resp.json())
|
||||
// .then(data => {
|
||||
// console.log("data", data);
|
||||
// })
|
||||
|
||||
|
||||
|
||||
})
|
Loading…
Reference in New Issue