Bootstrap 5 (for readers reaching this from the Bootstrap docs)
This is an old Bootstrap 3 question, but I haven't found any answers that address controlling the playback.
As stated in the Bootstrap docs, the question is referenced to address the issue of "the modal requires additional JavaScript not in Bootstrap to automatically stop playback and more"
The YouTube video will work as expected in the Bootstrap modal as long as you're using an iframe
instead of a video
element to prevent CORS errors. However, iframe
doesn't have video specific attributes like autoplay, loop, etc...
which means the only playback controls are those embedded in the YT video. For example, you can't autostart
the video when the modal opens (autostart=1 no longer works from the YT API)
The newer approach for controlling YouTube video playback is explained here. Here's how it would work specifically with video playback inside the Bootstrap 5 modal.
Modal markup
<div class="modal fade" id="dynamicVideoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0">
<div class="ratio ratio-21x9" id="player">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn-dark" id="playBtn">Play</button>
<button type="button" class="btn-dark" id="pauseBtn">Pause</button>
</div>
</div>
</div>
</div>
JavaScript
var player
function onYouTubeIframeAPIReady() {
console.log('onYouTubeIframeAPIReady...')
player = new YT.Player('player', {
videoId: 'M7lc1UVf-VE', // YT video source
playerVars: {
'playsinline': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
})
}
function onPlayerReady(event) {
event.target.playVideo() // autostart
}
function onPlayerStateChange(event) {
// do other custom stuff here by watching the YT.PlayerState
}
function loadYouTubeVideo() {
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
var myModalEl = document.getElementById('dynamicVideoModal')
myModalEl.addEventListener('show.bs.modal', function (event) {
// dynamically create video when modal is opened
loadYouTubeVideo()
})
// optional hooks for controls outside YT
var playBtn = document.getElementById('playBtn')
playBtn.addEventListener('click', function (event) {
console.log('play')
player.playVideo()
})
var pauseBtn = document.getElementById('pauseBtn')
pauseBtn.addEventListener('click', function (event) {
console.log('pause')
player.pauseVideo()
})
Bootstrap 5 YouTube Playback Demo
Update re: comment "problem is that video keeps playing when you close the modal window". This is out of scope from the OP question, but you'd simply hook into the modal hidden
event and run .stop() on the appropriate instance of the YT player. For example:
dynamicVideoModal.addEventListener('hidden.bs.modal', event => {
player.stopVideo()
})
Codeply (updated with stop on modal close)