I am trying to use turn.js to make a couple of audio flipbooks. In this case I have a single mp3 audio file and I want to play it starting from a startTime until and endTime page by page for pages supporting it. I am able to stop to play the audio after an interval but I did not find a solution to start to play the audio from a startTime > of 0 seconds.
This is my code:
let currentPage = 0; // Initialize the current page variable
let audio = null; // Initialize the audio variable
const DEBUG_MODE = true;
function debugLog(...args) {
if (DEBUG_MODE) {
console.log(...args);
}
}
function loadApp() {
var flipbook = $('.flipbook');
var audio = new Audio();
function playAudio(audioFile, startTime, endTime) {
stopAudio(); // Stop any currently playing audio
const audio = new Audio(audioFile);
let startTimeSet = false; // Flag variable to keep track of whether startTime has been set
// Debugging logs
debugLog(`Loading audio file: ${audioFile}`);
debugLog(`Start time: ${startTime}, End time: ${endTime}`);
audio.addEventListener('loadeddata', () => {
if (!startTimeSet) { // Only set startTime if it hasn't been set already
audio.currentTime = startTime;
debugLog(`Audio data loaded. Setting start time to: ${audio.currentTime}`);
startTimeSet = true; // Set the flag variable to true
audio.play();
}
});
audio.addEventListener('timeupdate', function() {
if (audio.currentTime >= endTime) {
stopAudio();
debugLog('Audio stopped automatically at the end time.');
}
});
audio.addEventListener('error', function(e) {
debugLog('Error during audio playback:', e);
});
audio.load(); // Load the audio file
debugLog('Audio loaded.');
}
function stopAudio() {
if (window.currentAudio) {
window.currentAudio.pause();
window.currentAudio = null;
}
}
function stopTTS() {
window.speechSynthesis.cancel();
}
function playTTS(text, lang) {
stopTTS();
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = lang;
window.speechSynthesis.speak(utterance);
}
function handlePageTurned(data, page) {
var pageIndex = page - 1; // Adjust for 0-based index
if (pageIndex < 0 || pageIndex >= data.pages.length) {
return;
}
var currentPage = data.pages[pageIndex];
var combinedAudio = currentPage.audio;
var combinedText = currentPage.text;
var combinedLang = currentPage.lang || navigator.language || 'it-IT';
debugLog('currentPage:', currentPage);
debugLog('currentPage.image:', currentPage.image);
debugLog('combinedAudio:', combinedAudio);
debugLog('currentPage.start_time:', currentPage.start_time);
debugLog('currentPage.end_time:', currentPage.end_time);
debugLog('combinedText:', combinedText);
debugLog('combinedLang:', combinedLang);
if (combinedAudio) {
playAudio(combinedAudio, currentPage.start_time, currentPage.end_time);
} else if (combinedText) {
playTTS(combinedText, combinedLang);
}
}
// Check if the CSS was already loaded
if (flipbook.width() == 0 || flipbook.height() == 0) {
setTimeout(loadApp, 10);
return;
}
// Fetch the JSON file
fetch('flipbook.json')
.then(response => response.json())
.then(data => {
debugLog('JSON data loaded:', data); // Debug: verifica i dati JSON caricati
// Loop through the pages in the JSON data
data.pages.forEach((page, index) => {
// Create a new page div
var newPage = document.createElement('div');
// Set the class based on the page type
if( page.type === 'hard' ) {
newPage.className = 'hard'
}
else if( page.type === 'left' ) {
newPage.className = 'page left'
}
else if( page.type === 'right' ) {
newPage.className = 'page right'
}
else if( (page.type === 'double' ) && (index % 2 === 0)) {
newPage.className = 'page double left'
}
else {
newPage.className = 'page double right'
}
// Set the background image
newPage.style.backgroundImage = `url(${page.image})`;
// Add data attributes for audio and text-to-speech
$(newPage).data('audio', page.audio);
$(newPage).data('text', page.text);
$(newPage).data('lang', page.lang);
$(newPage).data('startTime', page.start_time);
$(newPage).data('endTime', page.end_time);
// Append the new page div to the flipbook
flipbook.append(newPage);
});
// Apply the scissor effect to the soft pages
$('.flipbook .double').scissor();
// Create the flipbook
$('.flipbook').turn({
elevation: 50,
gradients: true,
autoCenter: true,
display: 'double', // Keep this as 'double' to maintain the original behavior for soft pages
pages: data.pages.length, // Set the total number of pages in the flipbook
when: {
turning: function(event, page, view) {
// Stop any current audio or TTS
stopAudio();
stopTTS();
// Ensure hard pages turn as single pages
if ($('.flipbook .page-wrapper').eq(page - 1).hasClass('hard')) {
$('.flipbook').turn('display', 'single');
} else if ($('.flipbook .page-wrapper').eq(page - 1).hasClass('double') && !$('.flipbook').turn('animating')) {
$('.flipbook').turn('display', 'double');
}
debugLog('Turning to page:', page); // Debug: verifica il numero di pagina che sta girando
},
turned: function(event, page, view) {
handlePageTurned(data, page);
}
}
});
})
.catch(error => console.error('Error:', error));
}
// Load the HTML4 version if there's not CSS transform
yepnope({
test: Modernizr.csstransforms,
yep: ['../../lib/turn.min.js'],
nope: ['../../lib/turn.html4.min.js'],
both: ['../../lib/scissor.min.js', 'css/double-page-hard.css'],
complete: loadApp
});
Every solution/suggestion is very welcome.