Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
83
Help us understand the problem. What is going on with this article?
@hadakadenkyu

【音声対応】 iPhone Safariで動画をインライン再生する方法続き

More than 5 years have passed since last update.

iPhone Safariで動画をインライン再生する方法への反応の中に「音声は?」との声がちらほらありました。
スマホは常にサイレントモードにしてて殆ど音出さないのですっかり頭から抜けていましたが、実験済みでしたので今回は音声付きでインライン再生する方法の話をば。

音声をAudio APIを使って同時に再生

最初に思いつくのは動画からDemuxして分離した音声をAudio APIを使って同時に再生する方法でしょう。
実際これで足りる場合もあります。が、足りない場合もあります。

VideoとAudioに同時に再生命令を送っても、同じ速さで再生されるかは保証されない

昔々にAviUTLだのTMPGEncだのでエンコしてた人なんかはわかると思いますが、分離された音声と映像は結構かんたんにズレます
まして今回はVideoをまともに再生していないわけで。
ですからナレーションとBGMのみのCMなんかは違和感もないでしょうが、人物が喋っていたりすると口パクがズレる可能性が高くなります。

音声を映像に同期する

通常、音声と映像を同期させる場合、映像を見ながら音声を映像に合わせる必要がありますが、今回の場合はそもそもVideoは再生せずにcurrentTimeを動かしていますので、普通にAudioを再生して

video.currentTime = audio.currentTime

とすれば同期が取れます。かんたん!

さらにシンプルに

ところで、規格がそうなっているのかはわかりませんが、Audio APIはソースに動画ファイルを入れると音声だけ再生されます

つまり、

動画を音声として再生してフレームレートごとにaudioのcurrentTimeをvideoに代入すればいい!

Sample Code

ボタンタップで再生/停止をトグル
(function(){
    var btn = document.querySelector('button');
    btn.disabled = true;
    var audio = new Audio();
    var video = document.createElement('video');
    video.style.display = 'none';
    document.body.appendChild(video);
    var canvas = document.getElementById('myCanvas');
    var ctx = canvas.getContext('2d');
    var togglePlay;
    var ua = navigator.userAgent;
    if(/(iPhone|iPod)/.test(ua)) { // iPadもVideoはインライン再生可能である
        ctx.scale(0.5,0.5);
        var prms1 = new Promise(function(resolve, reject) {
            video.addEventListener('canplay',function(){
                resolve();
            });
            video.addEventListener('error',function(){
                reject();
                alert('failed loading video');
            });
        });
        var prms2 = new Promise(function(resolve, reject) {
            audio.addEventListener('canplay',function(){
                resolve();
            });
            audio.addEventListener('error',function(){
                reject();
                alert('failed loading audio');
            });
        });
        Promise.all([prms1,prms2]).then(function(){
            btn.disabled = false;
        });
        video.src = 'movie.mp4';
        video.load();
        audio.src = 'movie.mp4'; // 動画ファイルを突っ込んでも再生される
        audio.load();

        togglePlay = function(){
            if(audio.paused){
                audio.play();
                (function loop(){
                    video.currentTime = audio.currentTime;
                    ctx.drawImage(video, 0, 0, 640, 360);
                    if(!audio.paused){
                        requestAnimationFrame( loop );
                    }
                })();
            } else {
                audio.pause();
            }
        };
    } else { // AndroidとかiPadなら素直にVideoタグで再生
        canvas.parentNode.insertBefore(video,canvas);
        video.style.display = 'block';
        video.addEventListener('canplay',function(){
            btn.disabled = false;
        });
        video.src = 'movie.mp4';
        video.load();
        canvas.parentNode.removeChild(canvas);
        togglePlay = function(){
            if(video.paused){
                video.play();
            } else {
                video.pause();
            }
        };
    }
    btn.addEventListener('click',togglePlay);
})();

DEMO

http://jsrun.it/hadakadenkyu/aYPw
http://jsrun.it/hadakadenkyu/aYPw

補足

  • タップ無しで再生出来ません。つまり自動再生が出来ません。
  • WebGLでもイケます。
  • 音が要らなくても寧ろvolumeを0にしてこっちでやった方がVideoの代わりにAudioを操作するだけなので筋が良いかもしれない。
83
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
83
Help us understand the problem. What is going on with this article?