Problema com iframes do YouTube em apps híbridos (APK) — solução prática

imagem de linguagem ícone de outros
	Desde outubro de 2025, desenvolvedores começaram a enfrentar um problema com vídeos do YouTube carregados via <iframe> dentro de apps híbridos (APK) — especialmente em WebView IOS. Até o momento, o YouTube / Google não se pronunciou oficialmente sobre a causa. A alternativa mais estável encontrada é: Não usar o iframe padrão do YouTube diretamente no app híbrido.
	
	Em vez disso: Criar uma página intermediária (player.html) O player.html: Carrega o vídeo via API oficial Escuta eventos do player Envia eventos para o app com postMessage

player.html (arquivo principal)

	Esse arquivo DEVE ser hospedado em uma URL pública (HTTPS).
	Exemplo: https://seusite.com/player.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    <meta name="referrer" content="strict-origin-when-cross-origin">
    <title>Player Youtube</title>

    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        html,
        body {
            width: 100%;
            height: 100%;
            overflow: hidden;
            background: #000;
        }

        #player {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        }
    </style>
</head>

<body>

    <div id="player"></div>

    <script src="https://www.youtube.com/iframe_api"></script>

    <script>
        let player;
        let videoId;
        let iframeId;

        function init() {

            const params = new URLSearchParams(window.location.search);
            videoId = params.get("v");
            iframeId = params.get('i');

            if (!videoId) {
                document.body.innerHTML = "sem video id";
                return;
            }

            if (window.YT && window.YT.Player) {
                createPlayer();
            } else {
                window.onYouTubeIframeAPIReady = createPlayer;
            }
        }

        function createPlayer() {

            if (player) return;

            player = new YT.Player('player', {
                videoId: videoId,
                host: 'https://www.youtube-nocookie.com',
                playerVars: {
                    autoplay: 0,
                    controls: 1,
                    rel: 0,
                    modestbranding: 1,
                    playsinline: 1,
                    enablejsapi: 1,
                    iv_load_policy: 3,
                    cc_load_policy: 0,
                    origin: window.location.origin
                },

                events: {
                    onStateChange: onStateChange
                }
            });
        }

        function onStateChange(e) {

            if (e.data === 1) {
                window.parent.postMessage({
                    type: "youtube-play",
                    iframeId: iframeId
                }, "*");
            }

            if (e.data === 2) {
                window.parent.postMessage({
                    type: "youtube-pause",
                    iframeId: iframeId
                }, "*");
            }

            if (e.data === 0) {
                window.parent.postMessage({
                    type: "youtube-ended",
                    iframeId: iframeId
                }, "*");
            }
        }

        init();
    </script>

</body>

</html>

index.html (exemplo de uso)

	Esse arquivo é apenas para teste local no navegador.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iframe youtube</title>
    <style>
        .container {
            width: 500px;
        }

        .video {
            position: relative;
            width: 100%;
            padding-bottom: 56.25%;
            height: 0;
        }

        .video iframe {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="video">
            <!--No src coloque a url completa onde hospedou o vídeo-->
            <!--v= é o id do vídeo que deseja exibir em tela-->
            <!--i= é o id do iframe para controle interno do app-->
            <iframe id="iframe01" src="/player.html?v=Ejkb_YpuHWs&loop=1&i=iframe01" frameborder="0"
                allowfullscreen></iframe>
        </div>
    </div>
</body>

<script>
    //listener para comunição pelo navegador com postMessage
    window.addEventListener("message", function (event) {
        //if (event.origin !== 'url aqui para segurança do app') return;
        const data = event.data;
        if (data.type === "youtube-play") {
            console.log("Vídeo iniciou:", data.iframeId);
        }
        if (data.type === "youtube-pause") {
            console.log("Vídeo pausou:", data.iframeId);
        }
        if (data.type === "youtube-ended") {
            console.log("Vídeo terminou:", data.iframeId);
        }
    });
</script>

</html>

Fluxo:

	Seu app carrega um iframe/WebView O iframe aponta para player.html O player envia eventos via postMessage O app escuta esses eventos.

Boas práticas

	Sempre usar HTTPS 
	Validar event.origin em produção 
	Hospedar player.html em domínio confiável

Exemplo de eventos disponíveis:

	Você recebe:
	
	youtube-play 
	youtube-pause 
	youtube-ended

Conclusão

	Enquanto o problema do YouTube não é resolvido oficialmente, essa abordagem:
	
	Funciona em APK híbrido 
	Evita bugs do iframe padrão 
	Permite controle total do player  
	É compatível com qualquer framework

Link para o projeto no github:

	https://github.com/KarinaBarros/Youtube-Player/



Data: 24/02/2026

Autor: Karina Ariane de Barros



Deixe seu comentário