File size: 3,764 Bytes
7822956
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import React, { useEffect, useRef } from 'react'

export default function AudioPlayer() {
  const audioRef = useRef(null)
  const hasStartedRef = useRef(false)

  useEffect(() => {
    const a = new Audio('/jeopardy-themelq.mp3')
    audioRef.current = a
    a.preload = 'auto'
    a.volume = 0.5
    a.loop = true

    const startPlayback = async () => {
      if (hasStartedRef.current) return
      try {
        await a.play()
        hasStartedRef.current = true
        console.log('Audio started playing')
      } catch (e) {
        console.log('Autoplay blocked, waiting for user interaction')
        // If autoplay is blocked, try again on first user interaction
        const startOnInteraction = () => {
          if (!hasStartedRef.current) {
            a.play()
              .then(() => {
                hasStartedRef.current = true
                console.log('Audio started after user interaction')
              })
              .catch((err) => {
                console.error('Failed to start audio:', err)
              })
          }
        }
        const events = ['click', 'keydown', 'touchstart', 'mousedown']
        events.forEach(event => {
          document.addEventListener(event, startOnInteraction, { once: true, passive: true })
        })
      }
    }

    // Handle if audio pauses unexpectedly
    const handlePause = () => {
      if (hasStartedRef.current && a.paused && document.visibilityState === 'visible') {
        console.log('Audio paused unexpectedly, restarting...')
        a.play().catch((err) => {
          console.error('Failed to restart audio:', err)
        })
      }
    }

    // Handle if audio stops unexpectedly
    const handleStalled = () => {
      if (hasStartedRef.current && a.paused) {
        console.log('Audio stalled, attempting to resume...')
        a.play().catch((err) => {
          console.error('Failed to resume audio:', err)
        })
      }
    }

    // Handle errors
    const handleError = (e) => {
      console.error('Audio error:', e)
      // Try to reload and play again
      a.load()
      if (hasStartedRef.current) {
        a.play().catch((err) => {
          console.error('Failed to restart after error:', err)
        })
      }
    }

    // Ensure audio continues playing when page becomes visible
    const handleVisibilityChange = () => {
      if (document.visibilityState === 'visible' && hasStartedRef.current && a.paused) {
        a.play().catch((err) => {
          console.error('Failed to resume on visibility change:', err)
        })
      }
    }

    // Try to play immediately when component mounts
    startPlayback()

    // Add event listeners
    a.addEventListener('pause', handlePause)
    a.addEventListener('stalled', handleStalled)
    a.addEventListener('error', handleError)
    document.addEventListener('visibilitychange', handleVisibilityChange)

    // Periodically check if audio is still playing and restart if needed
    const checkInterval = setInterval(() => {
      if (hasStartedRef.current && a.paused && document.visibilityState === 'visible') {
        console.log('Audio stopped, restarting...')
        a.play().catch((err) => {
          console.error('Failed to restart in interval check:', err)
        })
      }
    }, 2000) // Check every 2 seconds

    return () => {
      clearInterval(checkInterval)
      try {
        a.pause()
        a.src = ''
        a.removeEventListener('pause', handlePause)
        a.removeEventListener('stalled', handleStalled)
        a.removeEventListener('error', handleError)
        document.removeEventListener('visibilitychange', handleVisibilityChange)
      } catch (e) {
        console.error('Error cleaning up audio:', e)
      }
    }
  }, [])

  return null
}