77 votes

La vidéo HTML5 ne tourne pas en boucle

J'ai une vidéo en arrière-plan d'une page Web, et j'essaie de la faire tourner en boucle. Voici le code :

<video autoplay='true' loop='true' muted='true'>
  <source src='/admin/wallpapers/linked/4ebc66e899727777b400003c' type='video/mp4'></source>
</video>

Bien que j'aie demandé à la vidéo de tourner en boucle, elle ne le fait pas. J'ai également essayé de la faire tourner en boucle avec la fonction onended (conformément à ce fil de discussion sur l'assistance Mozilla J'ai également essayé ce bout de jQuery). Rien n'a fonctionné jusqu'à présent. Est-ce un problème avec Chrome, ou avec mon code ?

Edita:

J'ai vérifié les événements du réseau et le HEAD d'une copie de travail ( http://fhsclock-labs.heroku.com/no-violence ) par rapport à l'application que j'essaie de faire fonctionner. La différence est que la copie de travail sert la vidéo à partir d'un actif statique sur Heroku (via Varnish, apparemment), tandis que la mienne sert à partir de GridFS (MongoDB).

L'onglet Réseau de l'inspecteur de Chrome montre que dans mon application, la vidéo est demandée trois fois. La première fois, l'état est "en attente", la deuxième est "annulée" et la dernière est 200 OK. La copie de travail ne montre que deux demandes, l'une avec un statut "en attente" et l'autre avec un contenu partiel de 206. Cependant, une fois que la vidéo a été lue, la demande devient "annulée" et une autre demande est faite pour cette vidéo. Dans mon application, cela ne se produit pas.

En ce qui concerne le type, dans mon application, deux sont "indéfinis" et l'autre "vidéo/mp4" (ce qu'il est censé être). Dans l'application fonctionnelle, toutes les demandes sont "video/mp4".

De plus, je reçois Resource interpreted as Other but transferred with MIME type undefined. des avertissements dans la Console.

Je ne sais pas vraiment par où commencer. Je pense que le problème se situe du côté du serveur, car le fait de servir le fichier en tant que ressource statique fonctionne bien. Il se peut que le serveur n'envoie pas le bon type de contenu. Cela pourrait être un problème avec GridFS. Je n'en sais rien.

En tout cas, la source est aquí . Nous apprécions tout ce que vous pouvez nous dire à ce sujet.

3voto

Hataman Points 11

Pour tous ceux qui arrivent sur cette page 9 ans plus tard et si toutes les réponses ci-dessus n'ont pas fonctionné : J'ai eu ce problème aussi et je pensais que la source du problème était soit mes navigateurs, soit le serveur.

J'ai remarqué par la suite que les autres sites web sur Internet qui utilisent des vidéos en boucle n'ont pas de problème avec les vidéos en boucle. Pour résoudre le problème, j'ai téléchargé une vidéo aléatoire depuis l'un des sites, je l'ai visitée et téléchargée sur mon propre serveur et j'ai été ravi de constater qu'elle fonctionnait. Il semble donc que la source du problème soit la vidéo que j'utilisais.

J'ai ensuite corrigé ma vidéo avec un site de conversion vidéo en ligne (je ne veux pas en faire la publicité en particulier, mais les premiers qui ressortent d'une recherche rapide sur Google fonctionnent) et, hélas, cela a résolu le problème.

Je ne suis pas sûr de la véritable raison de ce problème. Je suppose qu'il y avait une erreur de conversion ou de compression de la vidéo originale qui m'a été remise par mon client.

2voto

ferne97 Points 747

Je sais que cela ne se rapporte pas exactement à la question posée, mais si quelqu'un tombe sur ce sujet alors qu'il a un problème similaire, assurez-vous que vos sources sont bien ordonnées.

J'étais en train de charger un mp4 et un webm et j'ai remarqué que la vidéo ne tournait pas en boucle dans Chrome. C'est parce que le webm était le premier source répertorié, de sorte que Chrome chargeait le webm et non le fichier mp4 .

J'espère que cela aidera quelqu'un d'autre qui rencontrera ce problème.

<video autoplay loop>
    <source src="/path-to-vid/video.mp4" type="video/mp4">
    <source src="/path-to-vid/video.webm" type="video/webm">
</video>

1voto

gabrielstuff Points 121

C'est super nul mais dropbox utilise le bon code de statut. Donc téléchargez sur dropbox et remplacez le www par dl.

Ainsi, en utilisant une url Dropbox, la vidéo est bien lue.

1voto

Mahdi Taleghani Points 11

J'ai eu le même problème et j'ai inévitablement résolu le problème en diffusant le contenu en continu.

Par exemple, voici le code avec le code html de la lame PHP Laravel qui demande une route de streaming :

<video>
    <source src="{{route('getVideoStream',$videoId)}}" type="video/mp4"/>
</video>

dans le contrôleur, je vais diffuser la vidéo et la renvoyer avec la fonction laravel stream :

   public function getVideoStream($videoId){

        $path = $pathOfVideo;

        $headers = [
            'Content-Type' => 'video/mp2t',
            'Content-Length' => File::size($path),
            'Content-Disposition' => 'attachment; filename="start.mp4"'
        ];

        $stream = new VideoStream($path);

        return response()->stream(function () use ($stream) {
            $stream->start();
        });
    }

et VideoStream Class est la classe de streaming que j'ai trouvée sur GitHub. Gist :

class VideoStream
{
    private $path = "";
    private $stream = "";
    private $buffer = 102400;
    private $start = -1;
    private $end = -1;
    private $size = 0;

    function __construct($filePath)
    {
        $this->path = $filePath;
    }

    /**
     * Open stream
     */
    private function open()
    {
        if (!($this->stream = fopen($this->path, 'rb'))) {
            die('Could not open stream for reading');
        }

    }

    /**
     * Set proper header to serve the video content
     */
    private function setHeader()
    {
        ob_get_clean();
        header("Content-Type: video/mp4");
        header("Cache-Control: max-age=2592000, public");
        header("Expires: " . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT');
        header("Last-Modified: " . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT');
        $this->start = 0;
        $this->size = filesize($this->path);
        $this->end = $this->size - 1;
        header("Accept-Ranges: 0-" . $this->end);

        if (isset($_SERVER['HTTP_RANGE'])) {

            $c_start = $this->start;
            $c_end = $this->end;

            list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
            if (strpos($range, ',') !== false) {
                header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            if ($range == '-') {
                $c_start = $this->size - substr($range, 1);
            } else {
                $range = explode('-', $range);
                $c_start = $range[0];

                $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
            }
            $c_end = ($c_end > $this->end) ? $this->end : $c_end;
            if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
                header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header("Content-Range: bytes $this->start-$this->end/$this->size");
                exit;
            }
            $this->start = $c_start;
            $this->end = $c_end;
            $length = $this->end - $this->start + 1;
            fseek($this->stream, $this->start);
            header('HTTP/1.1 206 Partial Content');
            header("Content-Length: " . $length);
            header("Content-Range: bytes $this->start-$this->end/" . $this->size);
        } else {
            header("Content-Length: " . $this->size);
        }

    }

    /**
     * close curretly opened stream
     */
    private function end()
    {
        fclose($this->stream);
        exit;
    }

    /**
     * perform the streaming of calculated range
     */
    private function stream()
    {
        $i = $this->start;
        set_time_limit(0);
        while (!feof($this->stream) && $i <= $this->end) {
            $bytesToRead = $this->buffer;
            if (($i + $bytesToRead) > $this->end) {
                $bytesToRead = $this->end - $i + 1;
            }
            $data = fread($this->stream, $bytesToRead);
            echo $data;
            flush();
            $i += $bytesToRead;
        }
    }

    /**
     * Start streaming video content
     */
    function start()
    {
        $this->open();
        $this->setHeader();
        $this->stream();
        $this->end();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X