Skip to content

Problem with safari and stream behind a proxy #1742

Open
@2803media

Description

The Problem

Strange thing happen here, with chrome and firefox everything works as expected but with safari I can load 2 times the stream and at the third it load for ever, if I change my IP with a VPN I can load 2 times and failed at the third again... This happen only with the stream url who need to be SSLify with the apache2 proxy

here is my howler config:

function createNewHowl() {
      setIsLoading(true); // Début du chargement du flux principal

      const timestamp = Date.now();
      const proxyUrl = streamUrl.startsWith("https://")
        ? `${streamUrl}`
        : `https://stream.domain.com?url=${streamUrl}?_=${timestamp}`;


      //console.log("Configuration du nouveau flux audio avec l'URL :", proxyUrl);

      soundRef.current = new Howl({
        src: [proxyUrl],
        html5: true,
        format: [
          "mp3",
          "mpeg",
          "opus",
          "ogg",
          "oga",
          "wav",
          "aac",
          "caf",
          "m4a",
          "m4b",
          "mp4",
          "weba",
          "webm",
          "dolby",
          "flac",
        ],
        volume: volume,
        autoUnlock: true,
        preload: true,
        pool: 1,
        xhr: {
          method: "GET",
          headers: {
            "Cache-Control": "no-cache",
            Pragma: "no-cache",
          },
        },
        onplay: () => {
          //console.log("Lecture du flux audio démarrée.");
          setIsPlaying(true);
          isManuallyPausedRef.current = false;
          setIsLoading(false); // Fin du chargement du flux principal
          setError(null);
          setIsReconnecting(false);
        },
        onloaderror: (id, error) => {
          console.error("Erreur de chargement audio (ID: " + id + "):", error);
          setError("Erreur de chargement du flux.");
          setIsLoading(false);
          handleReconnect();
        },
        onplayerror: (id, error) => {
          console.error("Erreur de lecture audio (ID: " + id + "):", error);
          setError("Erreur de lecture du flux.");
          setIsLoading(false);
          handleReconnect();
        },
        onend: () => {
          console.log(
            "Le flux audio s'est terminé, tentative de reconnexion..."
          );
          if (!isManuallyPausedRef.current) {
            handleReconnect();
          }
        },
      });

      // Démarre la lecture si le son n'est pas déjà en cours
      if (soundRef.current && !soundRef.current.playing()) {
        //console.log("Démarrage de la lecture du flux audio.");
        soundRef.current.play();
      } else {
        console.log(
          "Le son est déjà en cours de lecture ou n'a pas pu être chargé."
        );
      }
    }
  }, [streamUrl, handleReconnect]);

And my apache proxy config:

SSLProxyEngine On

    # Proxy settings for streaming
    <Proxy *>
        Require all granted
        Header merge Accept-Ranges bytes
        Header set Accept-Ranges bytes
        
        # Cache control headers - plus strict pour Safari
        Header set Cache-Control "no-cache, no-store, must-revalidate, private, max-age=0"
        Header set Pragma "no-cache"
        Header set Expires "-1"

        Header set Icy-Metadata 1        

        # Security headers
        Header always set X-Content-Type-Options "nosniff"
        Header always set X-Frame-Options "DENY"
        Header always set X-XSS-Protection "1; mode=block"
    </Proxy>

    # MIME Type Handling
    RewriteCond %{QUERY_STRING} url=.*\.(mp3|aac|ogg|opus|flac) [NC]
    RewriteRule ^ - [E=STREAM_TYPE:audio/%1]
    Header set Content-Type "%{STREAM_TYPE}e" env=STREAM_TYPE

    # Configuration spécifique pour Safari
    SetEnvIf User-Agent "Safari" is_safari=1
    SetEnvIf User-Agent "Safari" nokeepalive=1

    # Timeouts - configuration globale
    TimeOut 300
    KeepAliveTimeout 5
    MaxKeepAliveRequests 100

    # En-têtes conditionnels pour Safari
    Header set Connection "close" env=is_safari
    Header set Keep-Alive "timeout=5, max=100" env=!is_safari
    Header set X-Safari-Streaming "1" env=is_safari

    # Configuration du proxy optimisée
    <IfModule mod_proxy.c>
        # Un seul ProxyTimeout global
        ProxyTimeout 300
        
        ProxyBadHeader Ignore
        
        # Forcer HTTP/1.0 pour Safari
        SetEnvIf User-Agent "Safari" force-proxy-request-1.0=1
        SetEnvIf User-Agent "Safari" proxy-nokeepalive=1
        SetEnvIf User-Agent "Safari" downgrade-1.0=1
        SetEnv proxy-initial-not-pooled 1
        
        # Buffer size optimisé
        ProxyIOBufferSize 65536
    </IfModule>

    # CORS Headers
    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "GET, OPTIONS, HEAD"
    Header always set Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Icy-Metadata,If-Range"
    Header always set Access-Control-Expose-Headers "Accept-Ranges,Content-Range,Content-Length,Content-Type"
    Header always set Access-Control-Max-Age "1728000"

    # En-têtes de cache spécifiques pour le streaming
    Header set Cache-Control "no-cache, private, max-age=0" env=is_safari
    Header set Pragma "no-cache"
    Header set Expires "0"

    # Désactiver la compression pour les flux audio
    SetEnvIf Request_URI "\.(mp3|aac|ogg|opus|flac)$" no-gzip dont-vary

Thanks for you input and experience with proxy, howler and howler...

Reproducible Example

No response

Reproduction Steps

Load 3 times a proxy stream on safari browser

Possible Solution

No response

Context

No response

Howler.js Version

2.2.4

Affected Browser(s)/Versiuon(s)

safari 18.0.1

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions