Skip to content

Instantly share code, notes, and snippets.

@cf
Created November 23, 2024 07:56
Show Gist options
  • Save cf/fe578edee8a63977a9f5c47e84925cf4 to your computer and use it in GitHub Desktop.
Save cf/fe578edee8a63977a9f5c47e84925cf4 to your computer and use it in GitHub Desktop.
fix-shadertoy-soundcloud.js
EffectPass.prototype.LegacyNewTexture = EffectPass.prototype.LegacyNewTexture ? EffectPass.prototype.LegacyNewTexture : EffectPass.prototype.NewTexture;
EffectPass.prototype.NewTexture = function ( wa, slot, url, buffers, cubeBuffers, keyboard ) {
var me = this;
var renderer = this.mRenderer;
if( renderer===null ) return;
if (url && url.mType === "musicstream") {
// sound cloud
texture = {mInfo: url, globject: null, loaded: false, audio: document.createElement("video")};
texture.audio.loop = true;
texture.audio.mMuted = texture.audio.mForceMuted = texture.audio.muted = this.mForceMuted;
if (this.mForceMuted === true) texture.audio.volume = 0;
texture.audio.autoplay = false;
texture.audio.hasFalled = false;
texture.audio.mPaused = false;
texture.audio.mSound = {};
if (wa === null && this.mForceMuted === false) {
alert("Shadertoy: Web Audio not implement in this browser");
texture.audio.mForceMuted = true;
}
if (texture.audio.mForceMuted) {
texture.globject = renderer.CreateTexture(renderer.TEXTYPE.T2D,512,2,renderer.TEXFMT.C1I8,renderer.FILTER.LINEAR,renderer.TEXWRP.CLAMP,null);
texture.audio.mSound.mFreqData = new Uint8Array(512);
texture.audio.mSound.mWaveData = new Uint8Array(512);
texture.loaded = true;
}
texture.audio.addEventListener("canplay", function () {
if (texture === null || texture.audio === null || this.mForceMuted || texture.loaded === true) return;
texture.globject = renderer.CreateTexture( renderer.TEXTYPE.T2D, 512, 2, renderer.TEXFMT.C1I8, renderer.FILTER.LINEAR, renderer.TEXWRP.CLAMP, null );
texture.audio.mSound.mSource = wa.createMediaElementSource(texture.audio);
texture.audio.mSound.mAnalyser = wa.createAnalyser();
texture.audio.mSound.mGain = wa.createGain();
texture.audio.mSound.mSource.connect(texture.audio.mSound.mAnalyser);
texture.audio.mSound.mAnalyser.connect(texture.audio.mSound.mGain);
texture.audio.mSound.mGain.connect(me.mGainNode);
texture.audio.mSound.mFreqData = new Uint8Array(
texture.audio.mSound.mAnalyser.frequencyBinCount
);
texture.audio.mSound.mWaveData = new Uint8Array(
texture.audio.mSound.mAnalyser.frequencyBinCount
);
if (texture.audio.mPaused) {
texture.audio.pause();
} else {
texture.audio
.play()
.then(function () {})
.catch(function (e) {
console.log("error " + e);
});
}
texture.loaded = true;
});
texture.audio.addEventListener("error", function () {
texture.audio.hasFalled = true;
});
if (!texture.audio.mForceMuted) {
SC.resolve(
url.mSrc,
function (song) {
if (song.streamable === true) {
texture.audio.crossOrigin = "anonymous";
if(song.protocol === "hls"){
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(song.stream_url);
hls.attachMedia(texture.audio);
}else if (video.canPlayType('application/vnd.apple.mpegurl')) {
texture.audio.src = song.stream_url;
}
}else{
texture.audio.src = song.stream_url;
}
texture.audio.soundcloudInfo = song;
} else {
alert("Shadertoy: Soundcloud 3 - This track cannot be streamed");
}
},
function (error) {
if (me.mTextureCallbackFun !== null) {
me.mTextureCallbackFun( me.mTextureCallbackObj, slot, { wave: null }, false, 4, 0, -1.0, me.mID );
}
}
);
}
if (me.mTextureCallbackFun !== null) {
me.mTextureCallbackFun( me.mTextureCallbackObj, slot, { wave: null, info: texture.audio.soundcloudInfo }, false, 8, 0, -1.0, me.mID );
}
let returnValue = {
mFailed: false,
mNeedsShaderCompile: this.mInputs[slot] === null || (["texture","webcam","mic","music","musicstream","keyboard","video"].indexOf(this.mInputs[slot].mInfo.mType)===-1)
};
this.DestroyInput(slot);
this.mInputs[slot] = texture;
this.MakeHeader();
return returnValue;
} else {
return this.LegacyNewTexture(wa, slot, url, buffers, cubeBuffers, keyboard);
}
};
function loadHLSJS() {
if (window._HAS_LOADED_HLS_JS) {
return Promise.resolve(true);
}
const HLS_JS_URL =
"https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js";
const HLS_JS_HASH =
"sha384-9v3HcdYrO3D+OPDTjZ40RXocgE4GtXVCd3/mCS62JsM93JXgI1afJVuwjFvsu6ni";
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.integrity = HLS_JS_HASH;
script.crossOrigin = "anonymous";
script.onload = function () {
//do stuff with the script
window._HAS_LOADED_HLS_JS = true;
resolve(true);
};
script.src = HLS_JS_URL;
document.head.appendChild(script);
});
}
async function soundCloudFix(soundCloudURL) {
const resp = await fetch(
"https://shadertoyschls.9z.workers.dev/sc?url=" +
encodeURIComponent(soundCloudURL)
);
const respJson = await resp.json();
if (respJson.protocol === "hls") {
await loadHLSJS();
}
return respJson;
}
function newSCResolve(url, callback, onError) {
soundCloudFix(url).then(callback).catch(onError);
}
SC.resolve = newSCResolve;
if (gShaderID) {
loadShader(gShaderID);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment