I am trying to create and play a playlist manifest using HLS. I am looping over all the segment files to add their names to the file/provide their url, but when I run my function, I get the error below, which means it's not properly receiving the urls:
[error] > 0 while loading data:application/x-mpegURL;base64,undefined
Here's my code:
segment_files = ["https://gib.s3.amazonaws.com/segment/first.ts", "https://gib.s3.amazonaws.com/segment/2nd.ts", "https://gib.s3.amazonaws.com/segment/first.ts"
function create_manifest() {
if (hls == undefined) {
player = document.createElement("video");
document.body.appendChild(player);
player.pause();
player.src = "";
for (let ii = 0; ii < segment_files.length; i++) {
var segment = segment_files[ii];
}
var manifestfile = btoa(
`#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-PLAYLIST-TYPE:VOD\n#EXT-X-TARGETDURATION:11\n#EXTINF:10.000,\n${segment}\n#EXT-X-ENDLIST`
);
}
if (Hls.isSupported()) {
hls = new Hls({
debug: true,
enableWorker: true,
lowLatencyMode: true,
});
hls.attachMedia(player);
hls.loadSource("data:application/x-mpegURL;base64," + manifestfile);
player.muted = true;
player.play();
}
}
Related
I am trying to export JSON to a CSV file.
Previously I'm using this code below to export:
convertToCSV(objArray: any) {
var array = typeof objArray != "object" ? JSON.parse(objArray) : objArray;
var str = "";
for (var i = 0; i < array.length; i++) {
var line = "";
for (var index in array[i]) {
if (line != "") line += ",";
line += array[i][index];
}
str += line + "\r\n";
}
return str;
}
exportCSVFile(headers: any, items: any[], fileTitle: string) {
if (headers) {
items.unshift(headers);
}
// Convert Object to JSON
var jsonObject = JSON.stringify(items);
var csv = this.convertToCSV(jsonObject);
var exportedFilenmae = fileTitle + ".csv" || "export.csv";
var blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
if (navigator.msSaveBlob) {
// IE 10+
navigator.msSaveBlob(blob, exportedFilenmae);
} else {
var link = document.createElement("a");
if (link.download !== undefined) {
// feature detection
// Browsers that support HTML5 download attribute
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", exportedFilenmae);
link.style.visibility = "hidden";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
exportcsv() {
this.data.forEach((item) => {
this.itemsFormatted.push({
meteringpoint: item.meteringpoint.replace(/,/g, ""), // remove commas to avoid errors,
group: item.group,
instdevice: item.instdevice,
floor: item.floor,
room: item.room,
section: item.section,
});
});
var fileTitle = "Metering Point View"; // or 'my-unique-title'
this.exportCSVFile(this.headerCSV, this.itemsFormatted, fileTitle);
}
}
But there's an error with Property 'msSaveBlob' does not exist on type 'Navigator'
Here is what I found on the internet regarding the error
So I want to ask if there is any library for exporting that has a typescript definition or is there any workaround for the problem on the code above.
Most of the libraries i found will have this problem whereby Could not find a declaration file for module 'vue-json-to-csv'. 'd:/Project/Ivory-Leaf/OAMR/VueFrontEndUi/vuefrontendui/node_modules/vue-json-to-csv/dist/vue-json-to-csv.js' implicitly has an 'any' type. Try `npm i --save-dev #types/vue-json-to-csv` if it exists or add a new declaration (.d.ts) file containing `declare module 'vue-json-to-csv';
I have created a music playing flash, it works great and all when I'm running it from my local storage i.e (opening the swf directly from my computer)
but when I open the swf from a server it doesn't load the file. I've added the input handler below.
function addTrack(){
var trackChecker: URLLoader = new URLLoader();
if (String(path.text).substr(-4, 4) == ".mp3") {
txtError.text = "";
trackChecker.load(new URLRequest(String(path.text)))
} else {
if (String(path.text).substr(-4, 1) == ".") {
txtError.text = "Wrong format, tried to open " + String(path.text).substr(-4, 4) + ", but the only currently supported format is .mp3";
} else {
path.appendText(".mp3");
txtError.text = "";
trackChecker.load(new URLRequest(String(path.text)))
}
}
trackChecker.addEventListener(Event.COMPLETE, addToList);
trackChecker.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
}
function onIOError(e: IOErrorEvent) {
txtError.text = "No file found or file is damaged";
}
function addToList(e: Event) {
addedTrack = true;
tempSong = new Sound();
tempSong.load(new URLRequest(String(path.text)));
tempSong.addEventListener(Event.COMPLETE, tempData);
ActualArray[ActualArray.length] = ["Placeholder", "Placeholder", "Placeholder", "Placeholder", String(path.text)];
}
function tempData(e: Event) {
var tempTrackName;
var tempName: Array = tempSong.url.split("/");
if (String(tempSong.id3.songName) == "null") {
tempTrackName = String(tempName[tempName.length - 1].replace(".mp3", ""));
} else {
tempTrackName = (String(tempSong.id3.songName));
}
path.text = "";
for (var i: int = 3; i < tA.length - 1; i++) {
path.appendText(tempName[i]);
path.appendText("\\");
}
addToGrid(int(ActualArray.length - 1), tempSong.length, tempTrackName);
path.setSelection(path.text.length, path.text.length);
}
Worth noting that the script stops before it can change path.text, i.e. in the middle of "function tempData(e: Event)" or earlier. in stop i mean nothing happens, the other scripts work, but when you try to add a track nothing happens at all. but I can't recreate the glitch on my computer, because it only exists when the swf is hosted externally.
I would like to create a decibel meter for the audio that is playing in a video element. The video element is playing a WebRTC stream.
At the moment WebRTC streams cannot be passed into a Web Audio Analyzer. (Although this might change soon … ) (see Web Audio API analyser node getByteFrequencyData returning blank array)
Is there currently another way to get decibel information from a remote mediastream?
Chrome 50 was released: As of the 13th of April 2016 using an Analyser Node with a MediaStreamAudioSourceNode works fine to get audio levels. The resulting audioLevels value can be animated or simply passed into a html meter element.
var _mediaStream = SOME_LOCAL_OR_RTP_MEDIASTREAM;
var _audioContext = new AudioContext();
var _audioAnalyser = [];
var _freqs = [];
var audioLevels = [0];
var _audioSource = _audioContext.createMediaStreamSource(_mediaStream);
var _audioGain1 = _audioContext.createGain();
var _audioChannelSplitter = _audioContext.createChannelSplitter(_audioSource.channelCount);
_audioSource.connect(_audioGain1);
_audioGain1.connect(_audioChannelSplitter);
_audioGain1.connect(_audioContext.destination);
for (let i = 0; i < _audioSource.channelCount; i++) {
_audioAnalyser[i] = _audioContext.createAnalyser();
_audioAnalyser[i].minDecibels = -100;
_audioAnalyser[i].maxDecibels = 0;
_audioAnalyser[i].smoothingTimeConstant = 0.8;
_audioAnalyser[i].fftSize = 32;
_freqs[i] = new Uint8Array(_audioAnalyser[i].frequencyBinCount);
_audioChannelSplitter.connect(_audioAnalyser[i], i, 0);
}
function calculateAudioLevels() {
setTimeout(() => {
for (let channelI = 0; channelI < _audioAnalyser.length; channelI++) {
_audioAnalyser[channelI].getByteFrequencyData(_freqs[channelI]);
let value = 0;
for (let freqBinI = 0; freqBinI < _audioAnalyser[channelI].frequencyBinCount; freqBinI++) {
value = Math.max(value, _freqs[channelI][freqBinI]);
}
audioLevels[channelI] = value / 256;
}
requestAnimationFrame(calculateAudioLevels.bind(this));
}, 1000 / 15); // Max 15fps — not more needed
}
This is a good example:
https://webrtc.github.io/samples/src/content/getusermedia/volume/
And this is the source code:
https://github.com/webrtc/samples/tree/gh-pages/src/content/getusermedia/volume
And this is a sample:
function recordAudio() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.audioContext = new AudioContext();
const instantMeter = document.querySelector('#sound-meter');
const constraints = {'video': false, 'audio': true};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
window.stream = stream;
const soundMeter = window.soundMeter = new SoundMeter(window.audioContext);
soundMeter.connectToSource(stream, function(e) {
if (e) {
alert(e);
return;
}
setInterval(() => {
instantMeter.value = soundMeter.instant.toFixed(2);
}, 200);
});
$('#sound-meter').show();
$('#audio-icon').hide()
} catch(error) {
console.error('Error recording audio.', error);
}
}
could someone please help me to find out why this won't work on safari browser? It seems to work really well in all other browsers apart from Safari. I really could not work it out.
Any help will be most appreciated.
function loadPlayer()
{
var audioPlayer = new Audio();
audioPlayer.controls="";
audioPlayer.setAttribute("data-index", -1); //set default index to -1.
audioPlayer.addEventListener('ended',nextSong,false);
audioPlayer.addEventListener('error',errorFallback,true);
document.getElementById("player").appendChild(audioPlayer);
}
function nextSong(index, e)
{
var next;
var audioPlayer = document.getElementsByTagName('audio')[0];
//check for index. If so load from index. If not, index is defined auto iterate to next value.
if (index >= 0)
{
next = index;
}
else
{
next = parseInt(audioPlayer.getAttribute("data-index"))+1;
next >= urls.length ? next = 0 : null;
}
audioPlayer.src=urls[next][0]; //load the url.
audioPlayer.setAttribute("data-index", next);
//disable the player.
var audioPlayerControls = document.getElementById("playerControls");
audioPlayer.removeEventListener('canplay',enablePlayerControls,false);
audioPlayerControls.setAttribute("disabled", true);
audioPlayer.addEventListener('canplay',enablePlayerControls,false);
audioPlayer.load();
//show the image:
var image = document.getElementById("playerList").querySelectorAll("a")[next].querySelector("img").cloneNode();
image.style.width = "30px";
if(audioPlayerControls.querySelector("img"))
{
audioPlayerControls.replaceChild(image, audioPlayerControls.querySelector("img"));
}
else
{
audioPlayerControls.insertBefore(image, audioPlayerControls.querySelector("a"));
}
}
function enablePlayerControls()
{
//File has loaded, so we can start playing the audio.
//Enable the player options.
var audioPlayer = document.getElementsByTagName('audio')[0];
audioPlayer.removeEventListener('canplay',enablePlayerControls,false);
document.getElementById("playerControls").removeAttribute("disabled");
audioPlayer.play();
}
function errorFallback() {
nextSong();
}
function playPause()
{
var audioPlayer = document.getElementsByTagName('audio')[0];
if (audioPlayer.paused)
{
audioPlayer.play();
} else
{
audioPlayer.pause();
}
}
function pickSong(e)
{
//we want the correct target. Select it via the event (e).
var target;
//pickSong does the selecting:
if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() == "img")
{
//The event target = the img element.
target = e.target.parentElement;
}
else
{
//the event target is the a element
target = e.target;
}
var index = target.getAttribute("data-index"); //get the song index stored in the data-index attribute.
nextSong(index);
}
var urls = new Array();
urls[0] = ['http://mp3lg4.tdf-cdn.com/9079/jet_143844.mp3', 'http://radio-maghreb.net/radio/radio almazighia.png'];
urls[1] = ['http://mp3lg4.tdf-cdn.com/9077/jet_143651.mp3', "http://radio-maghreb.net/radio/alwatania.png"];
urls[2] = ['http://mp3lg4.tdf-cdn.com/9080/jet_144136.mp3', "http://radio-maghreb.net/radio/inter.jpg"];
function startAudioPlayer()
{
loadPlayer();
for (var i = 0; i < urls.length; ++i)
{
//this for loop runs through all urls and appends them to the player list. This smooths the adding off new items. You only have
//to declare them in the array, the script does the rest.
var link = document.createElement("a");
link.href = "javascript: void(0)";
link.addEventListener("click", pickSong, false);
link.setAttribute("data-index", i);
link.img = document.createElement("img");
link.img.src = urls[i][1];
link.appendChild(link.img);
document.getElementById("playerList").appendChild(link);
}
}
//Event that starts the audio player.
window.addEventListener("load", startAudioPlayer, false);
#playerControls[disabled=true] > a{
color: #c3c3c3;
}
<span id="playerControls" disabled="true">
Play
Stop
</span>
Next Track
<!-- player ends -->
<br>
<br>
<!-- img links start -->
<div id="playerList">
</div>
I'm building an audio player for a web experience, that has a list of tracks. Here is the code controlling the audio player.
$( document ).ready(function() {
jQuery(function($) {
var supportsAudio = !!document.createElement('audio').canPlayType;
if(supportsAudio) {
var index = 0,
playing = false;
mediaPath = 'audio/',
extension = '',
tracks = [
{"track":1,"name":"track1","length":"00:55","file":"track1"},
{"track":2,"name":"track2","length":"00:55","file":"track2"},
{"track":3,"name":"track3","length":"00:55","file":"track3"},
{"track":4,"name":"track4","length":"00:55","file":"track4"},
{"track":5,"name":"track5","length":"00:55","file":"track5"}
],
trackCount = tracks.length,
npAction = $('#npAction'),
npTitle = $('#npTitle'),
audio = $('#audio1').bind('play', function() {
playing = true;
npAction.text('Now Playing:');
}).bind('pause', function() {
playing = false;
npAction.text('Paused:');
}).bind('ended', function() {
npAction.text('Paused:');
if((index + 1) < trackCount) {
index++;
loadTrack(index);
audio.play();
} else {
audio.pause();
index = 0;
loadTrack(index);
}
}).get(0),
li = $('#plUL li').click(function() {
var id = parseInt($(this).index());
if(id !== index) {
playTrack(id);
}
}),
loadTrack = function(id) {
$('.plSel').removeClass('plSel');
$('#plUL li:eq(' + id + ')').addClass('plSel');
npTitle.text(tracks[id].name);
index = id;
audio.src = mediaPath + tracks[id].file + extension;
},
playTrack = function(id) {
loadTrack(id);
audio.play();
};
extension = audio.canPlayType('audio/mpeg') ? '.mp3' : audio.canPlayType('audio/ogg') ? '.ogg' : '';
loadTrack(index);
}
});
});
Is there a way to reorder the list inside of the variable named tracks? Generating the list of 1 through 5 in a random pull? for example, the items named track2 track3 track4 ect. could potentially be played first? I'm looking for that to be random on a page refresh.
Thanks for the help!
You could add a playOrder field to the tracks variable, and have a function go through each on on load and assign it a random unused playOrder number.