skylinkd commited on
Commit
a1f65b4
·
verified ·
1 Parent(s): bba812d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -42
app.py CHANGED
@@ -58,10 +58,6 @@ os.makedirs(TEMP_DIR, exist_ok=True)
58
  model_load_lock = Lock()
59
  loaded_detectors = {}
60
  whisper_model = None
61
- # --- ACTION REQUIRED ---
62
- # Please download a sound file, name it 'finish_sound.mp3',
63
- # and place it in the same directory as this app.py file.
64
- # A good one can be found here: https://cdn.pixabay.com/download/audio/2022/03/15/audio_2289a72212.mp3?filename=whistle-108713.mp3
65
 
66
  # --- Default Presets for Transfer Tab (Flat Dictionary) ---
67
  DEFAULT_LINK_PRESETS = {
@@ -1969,63 +1965,68 @@ bling_js = """
1969
  const a=document.createElement("script");a.setAttribute("src","https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js"),document.head.appendChild(a),a.onload=()=>{var e=confetti.create(null,{resize:!0,useWorker:!0});e({particleCount:150,spread:90,origin:{y:.6}})}
1970
  }
1971
 
1972
- // --- Audio Feedback with Delay and Echo ---
1973
  const skriptz_audio = {
1974
  context: null,
1975
- buffer: null,
1976
  isInitialized: false,
1977
  };
1978
 
1979
  async function init_audio() {
1980
  if (skriptz_audio.isInitialized) return;
1981
  try {
 
1982
  skriptz_audio.context = new (window.AudioContext || window.webkitAudioContext)();
1983
- // --- FIX FOR BROWSER AUTOPLAY POLICY ---
1984
  if (skriptz_audio.context.state === 'suspended') {
1985
  await skriptz_audio.context.resume();
1986
  }
1987
- const response = await fetch('/file=finish_sound.mp3');
1988
- if (!response.ok) {
1989
- console.warn(`Finish sound not loaded: ${response.status} ${response.statusText}. Ensure 'finish_sound.mp3' is in the root directory and 'allowed_paths' is set in demo.launch().`);
1990
- skriptz_audio.isInitialized = true;
1991
- return;
1992
- }
1993
- const arrayBuffer = await response.arrayBuffer();
1994
- skriptz_audio.buffer = await skriptz_audio.context.decodeAudioData(arrayBuffer);
1995
  } catch (e) {
1996
- console.error('Error initializing or decoding audio:', e);
1997
  }
1998
  skriptz_audio.isInitialized = true;
1999
  }
2000
 
2001
  async function play_finish_sound() {
2002
- if (!skriptz_audio.isInitialized || !skriptz_audio.context) {
 
2003
  await init_audio();
2004
  }
2005
- if (!skriptz_audio.buffer || !skriptz_audio.context) return;
2006
-
2007
- // --- FIX FOR BROWSER AUTOPLAY POLICY ---
2008
- if (skriptz_audio.context.state === 'suspended') {
2009
- await skriptz_audio.context.resume();
2010
- }
2011
-
2012
  const context = skriptz_audio.context;
2013
- const source = context.createBufferSource();
2014
- source.buffer = skriptz_audio.buffer;
2015
-
2016
- const delay = context.createDelay();
2017
- delay.delayTime.value = 0.25;
2018
-
2019
- const feedback = context.createGain();
2020
- feedback.gain.value = 0.4;
2021
-
2022
- source.connect(context.destination);
2023
- source.connect(delay);
2024
- delay.connect(feedback);
2025
- feedback.connect(delay);
2026
- delay.connect(context.destination);
 
 
 
 
 
 
2027
 
2028
- source.start(0);
 
 
 
 
 
 
 
 
 
 
 
 
 
2029
  }
2030
 
2031
  // --- Dynamic Page Title ---
@@ -2859,6 +2860,4 @@ if __name__ == "__main__":
2859
  try: shutil.rmtree(TEMP_DIR)
2860
  except OSError as e: print(f"Error removing temp directory {TEMP_DIR}: {e}")
2861
  os.makedirs(TEMP_DIR, exist_ok=True)
2862
- # --- THIS IS THE MAIN FIX ---
2863
- # Add allowed_paths to let Gradio serve the sound file from the current directory.
2864
- demo.launch(inbrowser=True, allowed_paths=["."])
 
58
  model_load_lock = Lock()
59
  loaded_detectors = {}
60
  whisper_model = None
 
 
 
 
61
 
62
  # --- Default Presets for Transfer Tab (Flat Dictionary) ---
63
  DEFAULT_LINK_PRESETS = {
 
1965
  const a=document.createElement("script");a.setAttribute("src","https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js"),document.head.appendChild(a),a.onload=()=>{var e=confetti.create(null,{resize:!0,useWorker:!0});e({particleCount:150,spread:90,origin:{y:.6}})}
1966
  }
1967
 
1968
+ // --- Audio Feedback with Synthesized Whistle ---
1969
  const skriptz_audio = {
1970
  context: null,
 
1971
  isInitialized: false,
1972
  };
1973
 
1974
  async function init_audio() {
1975
  if (skriptz_audio.isInitialized) return;
1976
  try {
1977
+ // Create AudioContext
1978
  skriptz_audio.context = new (window.AudioContext || window.webkitAudioContext)();
1979
+ // Resume context if suspended by browser's autoplay policy
1980
  if (skriptz_audio.context.state === 'suspended') {
1981
  await skriptz_audio.context.resume();
1982
  }
 
 
 
 
 
 
 
 
1983
  } catch (e) {
1984
+ console.error('Failed to initialize Web Audio API:', e);
1985
  }
1986
  skriptz_audio.isInitialized = true;
1987
  }
1988
 
1989
  async function play_finish_sound() {
1990
+ // Ensure audio context is ready
1991
+ if (!skriptz_audio.isInitialized) {
1992
  await init_audio();
1993
  }
 
 
 
 
 
 
 
1994
  const context = skriptz_audio.context;
1995
+ if (!context) return;
1996
+
1997
+ // Resume context if needed (e.g., after user interaction)
1998
+ if (context.state === 'suspended') {
1999
+ await context.resume();
2000
+ }
2001
+
2002
+ const now = context.currentTime;
2003
+
2004
+ // Create audio nodes
2005
+ const oscillator = context.createOscillator();
2006
+ const gainNode = context.createGain();
2007
+
2008
+ // Connect nodes: Oscillator -> Gain -> Output
2009
+ oscillator.connect(gainNode);
2010
+ gainNode.connect(context.destination);
2011
+
2012
+ // --- Configure Sound ---
2013
+ // Oscillator for the tone
2014
+ oscillator.type = 'sine';
2015
 
2016
+ // Pitch envelope (the "whistle" sound)
2017
+ const startFreq = 2000;
2018
+ const endFreq = 1000;
2019
+ oscillator.frequency.setValueAtTime(startFreq, now);
2020
+ oscillator.frequency.exponentialRampToValueAtTime(endFreq, now + 0.15);
2021
+
2022
+ // Volume envelope (to make it short and prevent clicks)
2023
+ gainNode.gain.setValueAtTime(0, now);
2024
+ gainNode.gain.linearRampToValueAtTime(0.4, now + 0.02); // Quick fade-in
2025
+ gainNode.gain.linearRampToValueAtTime(0, now + 0.15); // Fade-out with pitch drop
2026
+
2027
+ // Start and stop the sound
2028
+ oscillator.start(now);
2029
+ oscillator.stop(now + 0.2);
2030
  }
2031
 
2032
  // --- Dynamic Page Title ---
 
2860
  try: shutil.rmtree(TEMP_DIR)
2861
  except OSError as e: print(f"Error removing temp directory {TEMP_DIR}: {e}")
2862
  os.makedirs(TEMP_DIR, exist_ok=True)
2863
+ demo.launch(inbrowser=True)