質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • PHP

    20298questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • JavaScript

    16362questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • YouTube API

    93questions

    YouTube APIはYouTubeのビデオコンテンツと機能性をウェブサイト、アプリケーション、デバイスに統合することを可能にします。

PHPとJavascriptを使って、Youtube Player API経由で動画を複数埋め込む方法

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 723

MRK

score 2

PHPとJavascriptを使って後述する仕様のページを作ろうとしているのですが、どうしてもうまくいかない部分があり、質問させて頂きます。

使用言語とAPI

目指している仕様

  • Youtube Player APIを使用して動画を複数埋め込む。
  • サムネイル画像をクリックするとモーダルウィンドウが出現し、動画再生開始。
  • 1つの動画につき、最初の一回の再生時に、10秒間の広告が流れる。
  • 広告は5秒後にスキップ可能。
  • モーダルウィンドウは「Close」ボタン、或はモーダルウィンドウの外側をクリックすると閉じ、動画も一時停止する。
  • 閉じたモーダルウィンドウのサムネイル画像を再度クリックすると、モーダルウィンドウが再度開き、動画の続きが自動的に再生される(広告は流れない)。

コード

現在、以下のようなコードを書きましたが、後述する問題点が発生し、解決できずにいます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Modal Window</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>

<?php $youtube_id_list = array("vH_hAucdcQM", "g-FpDQ8Eqw8", "H2aW5V46khA"); ?>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>



<?php foreach ($youtube_id_list as $key => $youtube_id): ?>
<div>

    <div id="open_<?php echo $key; ?>" class="open"><img src="http://i.ytimg.com/vi/<?php echo $youtube_id; ?>/sddefault.jpg" width="200px"></div>
    <div id="mask_<?php echo $key; ?>" class="mask hidden"></div>
    <div id="modal_<?php echo $key; ?>" class="mask hidden">
        <div id="sample_<?php echo $key; ?>"></div>

        <!--広告スペース-->
        <div id="ad_<?php echo $key; ?>" class="ad" style="display:none;">
            <div id="count-down_<?php echo $key; ?>" class="count-down"><span id="timer_<?php echo $key; ?>">05.00</span>秒後にスキップ可能</div>
            <button id="skip_<?php echo $key; ?>" style="display:none;">広告をスキップ</button>
        </div>
        <div id="gaugeBack_<?php echo $key; ?>" class="gaugeBack" style="display:none"></div>
        <div id="gauge_<?php echo $key; ?>" class="gauge" style="display:none"></div>
        <!--/広告スペース-->

        <div id="close_<?php echo $key; ?>" class="close">Close</div>
    </div>
</div>
<?php endforeach; ?>



<script>
<?php foreach ($youtube_id_list as $key => $youtube_id): ?>
(function() {
    'use strict';

    var open = document.getElementById('open_<?php echo $key; ?>');
    var close = document.getElementById('close_<?php echo $key; ?>');
    var modal = document.getElementById('modal_<?php echo $key; ?>');
    var mask = document.getElementById('mask_<?php echo $key; ?>');

    open.addEventListener('click', function() {
        modal.className = 'modal';
        mask.className = 'mask';
    });

    close.addEventListener('click', function() {
        modal.className = 'modal hidden';
        mask.className = 'mask hidden';
    });

    mask.addEventListener('click', function() {
        close.click();
    });
})();
<?php endforeach; ?>
</script>


<script>
// IFrame Player API の読み込み
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// YouTube ID と埋め込むエリア
var youtubeData = [
    <?php foreach ($youtube_id_list as $key => $youtube_id): ?>
    {
        youtubeIid: '<?php echo $youtube_id; ?>',
        embedArea: 'sample_<?php echo $key; ?>'
    }
    <?php
    if($youtube_id != end($youtube_id_list)) {
        echo ",";
    }
    ?>
    <?php endforeach; ?>
];

// サムネイルの埋め込み
function onYouTubeIframeAPIReady() {
  for (var i = 0; i < youtubeData.length; i++) {
    //document.getElementById(youtubeData[i]['embedArea']).innerHTML = '<img id="yt-thumb' + i + '" src="http://i.ytimg.com/vi/' + youtubeData[i]['youtubeIid'] + '/sddefault.jpg">';
    // 埋め込んだサムネイルにイベント追加
    embedYoutube(i);
  }
}

// YouTubeの埋め込みの準備
var ytPlayer;
function embedYoutube(num) {

    var i = 0;

    // サムネイルクリック
    document.getElementById('open_' + num).addEventListener('click', function() {

        if(i == 0) {
            $("#ad_" + num).show();
            $("#gaugeBack_" + num).show();
            $( "#gauge_" + num ) . animate( { width: 'toggle',}, { duration: 10000, easing: 'swing', } );

            setTimeout(function() {
                $("#count-down_" + num).hide();
                $("#skip_" + num).show();
            }, 5000);

            // スキップボタンがクリックされた時の処理
            $('#skip_' + num).click(function() {
                $("#ad_" + num).hide();
                $("#gauge_" + num).hide();
                $("#gaugeBack_" + num).hide();
                clearTimeout(playVideoTimer);

                ytPlayer = new YT.Player(
                    youtubeData[num]['embedArea'], // 埋め込む場所の指定
                    {
                        width: 640, // プレーヤーの幅
                        height: 390, // プレーヤーの高さ
                        videoId: youtubeData[num]['youtubeIid'], // YouTubeのID
                        events: {
                            'onReady': onPlayerReady,
                            'onStateChange': onPlayerStateChange // プレーヤーの状態が変更されたときに実行
                        }
                    }
                );

                return;
            });
            i++;

            // 10秒後に動画再生
            playVideoTimer = setTimeout(function(){

                $("#ad_" + num).hide();
                $("#gauge_" + num).hide();
                $("#gaugeBack_" + num).hide();

                ytPlayer = new YT.Player(
                    youtubeData[num]['embedArea'], // 埋め込む場所の指定
                    {
                        width: 640, // プレーヤーの幅
                        height: 390, // プレーヤーの高さ
                        videoId: youtubeData[num]['youtubeIid'], // YouTubeのID
                        events: {
                            'onReady': onPlayerReady,
                            'onStateChange': onPlayerStateChange // プレーヤーの状態が変更されたときに実行
                        }
                    }
                );
            },10000);
        }


        else {
            document.getElementById('open_' + num).addEventListener('click', function() {
                $("#ad_" + num).hide();
                $("#gauge_" + num).hide();
                $("#gaugeBack_" + num).hide();

                ytPlayer = new YT.Player(
                    youtubeData[num]['embedArea'], // 埋め込む場所の指定
                    {
                        width: 640, // プレーヤーの幅
                        height: 390, // プレーヤーの高さ
                        videoId: youtubeData[num]['youtubeIid'], // YouTubeのID
                        events: {
                            'onReady': onPlayerReady,
                            'onStateChange': onPlayerStateChange // プレーヤーの状態が変更されたときに実行
                        }
                    }
                );
            });
        }



        document.getElementById('close_' + num).addEventListener('click', function() {
            clearTimeout(playVideoTimer);
        });

        document.getElementById('mask_' + num).addEventListener('click', function() {
            document.getElementById('close_'  + num).click();
        });

    });
}

// プレーヤー読み込み後の処理
function onPlayerReady(event) {
    event.target.playVideo();

    <?php foreach ($youtube_id_list as $key => $youtube_id): ?>
    document.getElementById('close_<?php echo $key; ?>').addEventListener('click', function() {
            ytPlayer.pauseVideo();
    });

    document.getElementById('mask_<?php echo $key; ?>').addEventListener('click', function() {
        document.getElementById('close_<?php echo $key; ?>').click();
    });
    <?php endforeach; ?>
}


// プレーヤーの状態が変更されたとき
function onPlayerStateChange(event) {
   // 現在のプレーヤーの状態を取得
   var ytStatus = event.data;
  // 再生終了したとき
 if (ytStatus == YT.PlayerState.ENDED) {
     console.log('再生終了');
      // 動画再生
     event.target.playVideo();
   }
   // 再生中のとき
   if (ytStatus == YT.PlayerState.PLAYING) {
       console.log('再生中');
   }
   // 停止中のとき
   if (ytStatus == YT.PlayerState.PAUSED) {
        console.log('停止中');
   }
   // バッファリング中のとき
  if (ytStatus == YT.PlayerState.BUFFERING) {
     console.log('バッファリング中');
  }
   // 頭出し済みのとき
 if (ytStatus == YT.PlayerState.CUED) {
      console.log('頭出し済み');
 }
}
</script>


</body>
</html>

問題点

  • Closeボタン(或はモーダルウィンドウの外側)をクリックし、動画を一時停止にするプログラムが、2回目までは正常に作動するのですが、3回目以降はコンソールログに下記のエラーが発生し、正常に作動しない。

sample.php:425 Uncaught TypeError: ytPlayer.pauseVideo is not a function
at HTMLDivElement.<anonymous> (sample.php:425)
at HTMLDivElement.<anonymous> (sample.php:268)

  • 広告を表示中にCloseボタン(或はモーダルウィンドウの外側)をクリックし、広告の表示時間(10秒以内)中に再度サムネイルをクリックしてモーダルウィンドウを出すと、広告終了後、動画の再生が始まらない。

  • コードの下記の部分を削除すると、上記のCloseボタンの問題は起きないのですが、広告が自動で消えてくれないのと、動画の再生が自動的に始まらない(該当コードを削除しているので当然ではありますが)。

else {
    document.getElementById('open_' + num).addEventListener('click', function() {
        $("#ad_" + num).hide();
        $("#gauge_" + num).hide();
        $("#gaugeBack_" + num).hide();

        ytPlayer = new YT.Player(
            youtubeData[num]['embedArea'], // 埋め込む場所の指定
            {
                width: 640, // プレーヤーの幅
                height: 390, // プレーヤーの高さ
                videoId: youtubeData[num]['youtubeIid'], // YouTubeのID
                events: {
                    'onReady': onPlayerReady,
                    'onStateChange': onPlayerStateChange // プレーヤーの状態が変更されたときに実行
                }
            }
        );
    });
}

補足

  • Javascriptの中にPHPのコードが埋め込まれていたり、関数化すべきところができてなかったりといった、質問事項以外でのツッコミどころも多々あるかと思いますが、何分未熟者故に、ご容赦頂けましたら幸いです。勿論、そういった点のアドバイスも頂ける場合も、私としましては大歓迎です。
  • Closeボタンを押してモーダルウィンドウを閉じて動画を一時停止した後、再度モーダルウィンドウを出した際に、自動で動画が再生されるようにしたいのですが、上記の問題が発生したため、この部分は未実装状態となっています。いずれ実装する予定です。

参考にしたサイト

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

自己解決しました。

再生するたびに下記のコードを記述していましたが、それがエラーの元でした。

ytPlayer = new YT.Player(
    youtubeData[num]['embedArea'], // 埋め込む場所の指定
    {
        width: 640, // プレーヤーの幅
        height: 390, // プレーヤーの高さ
        videoId: youtubeData[num]['youtubeIid'], // YouTubeのID
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange // プレーヤーの状態が変更されたときに実行
        }
    }
);


上記のコードは最初に一度呼び出したら、あとは再生時には、下記のコードを記述するだけでOKでした。

ytPlayer.playVideo();

他、広告を表示するタイミング等、細かな修正をすることで、目指していた仕様通りの動作が出来ました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20298questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • JavaScript

    16362questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • YouTube API

    93questions

    YouTube APIはYouTubeのビデオコンテンツと機能性をウェブサイト、アプリケーション、デバイスに統合することを可能にします。