
// [START SCRIPT]
function patchEffectPassNewTexture(oldScript){
  const newTextureStart = oldScript.indexOf("EffectPass.prototype.NewTexture");
  const newTextureReturn = oldScript.lastIndexOf("return { mFailed: true };");
  if(newTextureStart === -1 || newTextureReturn < newTextureStart) return alert("could not patch EffectPass.prototype.NewTexture, HLS streams will not work");
  const functionBody = oldScript.substring(newTextureStart, newTextureReturn+25)+"
};";
  eval(
    functionBody
      .replace("texture.audio = document.createElement('audio')","texture.audio = document.createElement('video')")
      .replace("SC.resolve(url.mSrc,", "scResolvePatched(url.mSrc,texture,")
  );
}
function loadHLSJS() {
  if (window._HAS_LOADED_HLS_JS && window.Hls) return Promise.resolve(true);
  return new Promise((resolve) => {
    const script = document.createElement("script");
    script.integrity = "sha256-fEfNl9em57mNliPdjtmm1Fr0vkCF4MIAHNcXXCtM+wc=";
    script.crossOrigin = "anonymous";
    script.onload = () => resolve(window._HAS_LOADED_HLS_JS = true);
    script.onerror = () => {
      console.error("Failed to load HLS.js, HLS streams will not work");
      resolve(window._HAS_LOADED_HLS_JS = false);
    };
    script.src = "https://cdn.jsdelivr.net/npm/hls.js@1.6.13/dist/hls.min.js";
    document.head.appendChild(script);
  });
}
async function soundCloudFix(soundCloudURL) {
  const [resp] = await Promise.all([fetch("https://scloud-shadertoy-v2.9z.workers.dev/sc?url="+encodeURIComponent(soundCloudURL)), loadHLSJS()])
  const respJson = await resp.json();
  return respJson;
}
function scResolvePatched(url, texture, _callback, onError) {
  console.log("Loading SoundCloud URL: ", url);
  soundCloudFix(url).then((songResult) => {
    console.log("Resolved SoundCloud song: ", songResult);
    const song = songResult.legacy || songResult.standard;
    texture.audio.crossOrigin = "anonymous";
    if(song.protocol.indexOf("hls") !== -1 && window.Hls && window.Hls.isSupported()) { 
      const hls = new Hls();
      hls.loadSource(song.stream_url);
      hls.attachMedia(texture.audio);
    }else{
      if(song.protocol.indexOf("hls")!==-1){
        console.error("HLS stream but HLS.js not supported, trying to play directly");
      }
      texture.audio.src = song.stream_url;
    }
    texture.audio.soundcloudInfo = songResult;
  }).catch(onError);
}
function runFix() {
  patchEffectPassNewTexture(
    Array.from(document.head.getElementsByTagName("script"))
      .map((x) => x.innerHTML)
      .filter((x) => x.indexOf("EffectPass.prototype.NewTexture") !== -1)[0]
  );
  SC.resolve = function (url, callback, onError) { soundCloudFix(url).then(callback).catch(onError); };
  if (gShaderID) {
    loadShader(gShaderID);
  }
}
setTimeout(runFix, 5000);
// [END SCRIPT]
console.log("SoundCloud HLS patch loaded");
