mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Merge pull request #10427 from ctrlaltdavid/21334
Fix erroneous "did not start playing recording" messages
This commit is contained in:
commit
b0d2de7bc0
2 changed files with 118 additions and 59 deletions
|
@ -14,6 +14,7 @@
|
|||
|
||||
var APP_NAME = "PLAYBACK",
|
||||
HIFI_RECORDER_CHANNEL = "HiFi-Recorder-Channel",
|
||||
RECORDER_COMMAND_ERROR = "error",
|
||||
HIFI_PLAYER_CHANNEL = "HiFi-Player-Channel",
|
||||
PLAYER_COMMAND_PLAY = "play",
|
||||
PLAYER_COMMAND_STOP = "stop",
|
||||
|
@ -47,9 +48,17 @@
|
|||
searchState = SEARCH_IDLE,
|
||||
otherPlayersPlaying,
|
||||
otherPlayersPlayingCounts,
|
||||
pauseCount;
|
||||
pauseCount,
|
||||
isDestroyLater = false,
|
||||
|
||||
destroy;
|
||||
|
||||
function onUpdateTimestamp() {
|
||||
if (isDestroyLater) {
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
userData.timestamp = Date.now();
|
||||
Entities.editEntity(entityID, { userData: JSON.stringify(userData) });
|
||||
EntityViewer.queryOctree(); // Keep up to date ready for find().
|
||||
|
@ -69,12 +78,14 @@
|
|||
|
||||
if (sender !== scriptUUID) {
|
||||
message = JSON.parse(message);
|
||||
index = otherPlayersPlaying.indexOf(message.entity);
|
||||
if (index !== -1) {
|
||||
otherPlayersPlayingCounts[index] += 1;
|
||||
} else {
|
||||
otherPlayersPlaying.push(message.entity);
|
||||
otherPlayersPlayingCounts.push(1);
|
||||
if (message.playing !== undefined) {
|
||||
index = otherPlayersPlaying.indexOf(message.entity);
|
||||
if (index !== -1) {
|
||||
otherPlayersPlayingCounts[index] += 1;
|
||||
} else {
|
||||
otherPlayersPlaying.push(message.entity);
|
||||
otherPlayersPlayingCounts.push(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,10 +94,11 @@
|
|||
// Create a new persistence entity (even if already have one but that should never occur).
|
||||
var properties;
|
||||
|
||||
log("Create recording " + filename);
|
||||
log("Create recording entity for " + filename);
|
||||
|
||||
if (updateTimestampTimer !== null) {
|
||||
Script.clearInterval(updateTimestampTimer); // Just in case.
|
||||
if (updateTimestampTimer !== null) { // Just in case.
|
||||
Script.clearInterval(updateTimestampTimer);
|
||||
updateTimestampTimer = null;
|
||||
}
|
||||
|
||||
searchState = SEARCH_IDLE;
|
||||
|
@ -114,6 +126,7 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
log("Could not create recording entity for " + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -224,7 +237,7 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
destroy = function () {
|
||||
// Delete current persistence entity.
|
||||
if (entityID !== null) { // Just in case.
|
||||
Entities.deleteEntity(entityID);
|
||||
|
@ -233,7 +246,13 @@
|
|||
}
|
||||
if (updateTimestampTimer !== null) { // Just in case.
|
||||
Script.clearInterval(updateTimestampTimer);
|
||||
updateTimestampTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
function destroyLater() {
|
||||
// Schedules a call to destroy() when timer threading suits.
|
||||
isDestroyLater = true;
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
|
@ -254,6 +273,7 @@
|
|||
create: create,
|
||||
find: find,
|
||||
destroy: destroy,
|
||||
destroyLater: destroyLater,
|
||||
setUp: setUp,
|
||||
tearDown: tearDown
|
||||
};
|
||||
|
@ -261,41 +281,78 @@
|
|||
|
||||
Player = (function () {
|
||||
// Recording playback functions.
|
||||
var isPlayingRecording = false,
|
||||
var userID = null,
|
||||
isPlayingRecording = false,
|
||||
recordingFilename = "",
|
||||
autoPlayTimer = null,
|
||||
|
||||
autoPlay,
|
||||
playRecording;
|
||||
|
||||
function play(recording, position, orientation) {
|
||||
function error(message) {
|
||||
// Send error message to user.
|
||||
Messages.sendMessage(HIFI_RECORDER_CHANNEL, JSON.stringify({
|
||||
command: RECORDER_COMMAND_ERROR,
|
||||
user: userID,
|
||||
message: message
|
||||
}));
|
||||
}
|
||||
|
||||
function play(user, recording, position, orientation) {
|
||||
var errorMessage;
|
||||
|
||||
if (autoPlayTimer) { // Cancel auto-play.
|
||||
// FIXME: Once in a while Script.clearTimeout() fails.
|
||||
// [DEBUG] [hifi.scriptengine] [3748] [agent] stopTimer -- not in _timerFunctionMap QObject(0x0)
|
||||
Script.clearTimeout(autoPlayTimer);
|
||||
autoPlayTimer = null;
|
||||
}
|
||||
|
||||
userID = user;
|
||||
|
||||
if (Entity.create(recording, position, orientation)) {
|
||||
log("Play new recording " + recordingFilename);
|
||||
isPlayingRecording = true;
|
||||
log("Play recording " + recording);
|
||||
isPlayingRecording = true; // Immediate feedback.
|
||||
recordingFilename = recording;
|
||||
playRecording(recordingFilename, position, orientation);
|
||||
playRecording(recordingFilename, position, orientation, true);
|
||||
} else {
|
||||
log("Could not create entity to play new recording " + recordingFilename);
|
||||
errorMessage = "Could not persist recording " + recording.slice(4); // Remove leading "atp:".
|
||||
log(errorMessage);
|
||||
error(errorMessage);
|
||||
|
||||
autoPlayTimer = Script.setTimeout(autoPlay, AUTOPLAY_ERROR_INTERVAL); // Resume auto-play later.
|
||||
}
|
||||
}
|
||||
|
||||
function autoPlay() {
|
||||
autoPlay = function () {
|
||||
var recording,
|
||||
AUTOPLAY_SEARCH_DELTA = 1000;
|
||||
|
||||
// Random delay to help reduce collisions between AC scripts.
|
||||
Script.setTimeout(function () {
|
||||
// Guard against Script.clearTimeout() in play() not always working.
|
||||
if (isPlayingRecording) {
|
||||
return;
|
||||
}
|
||||
|
||||
recording = Entity.find();
|
||||
if (recording) {
|
||||
log("Play persisted recording " + recordingFilename);
|
||||
playRecording(recording.recording, recording.position, recording.orientation);
|
||||
log("Play persisted recording " + recording.recording);
|
||||
userID = null;
|
||||
autoPlayTimer = null;
|
||||
isPlayingRecording = true; // Immediate feedback.
|
||||
recordingFilename = recording.recording;
|
||||
playRecording(recording.recording, recording.position, recording.orientation, false);
|
||||
} else {
|
||||
autoPlayTimer = Script.setTimeout(autoPlay, AUTOPLAY_SEARCH_INTERVAL); // Try again soon.
|
||||
}
|
||||
}, Math.random() * AUTOPLAY_SEARCH_DELTA);
|
||||
}
|
||||
};
|
||||
|
||||
playRecording = function (recording, position, orientation) {
|
||||
playRecording = function (recording, position, orientation, isManual) {
|
||||
Recording.loadRecording(recording, function (success) {
|
||||
var errorMessage;
|
||||
|
||||
if (success) {
|
||||
Users.disableIgnoreRadius();
|
||||
|
||||
|
@ -310,15 +367,22 @@
|
|||
Recording.setPlayerLoop(true);
|
||||
Recording.setPlayerUseSkeletonModel(true);
|
||||
|
||||
isPlayingRecording = true;
|
||||
recordingFilename = recording;
|
||||
|
||||
Recording.setPlayerTime(0.0);
|
||||
Recording.startPlaying();
|
||||
|
||||
UserActivityLogger.logAction("playRecordingAC_play_recording");
|
||||
} else {
|
||||
log("Failed to load recording " + recording);
|
||||
if (isManual) {
|
||||
// Delete persistence entity if manual play request.
|
||||
Entity.destroyLater(); // Schedule for deletion; works around timer threading issues.
|
||||
}
|
||||
|
||||
errorMessage = "Could not load recording " + recording.slice(4); // Remove leading "atp:".
|
||||
log(errorMessage);
|
||||
error(errorMessage);
|
||||
|
||||
isPlayingRecording = false;
|
||||
recordingFilename = "";
|
||||
autoPlayTimer = Script.setTimeout(autoPlay, AUTOPLAY_ERROR_INTERVAL); // Try again later.
|
||||
}
|
||||
});
|
||||
|
@ -374,7 +438,15 @@
|
|||
recording: Player.recording(),
|
||||
entity: Entity.id()
|
||||
}));
|
||||
heartbeatTimer = Script.setTimeout(sendHeartbeat, HEARTBEAT_INTERVAL);
|
||||
}
|
||||
|
||||
function onHeartbeatTimer() {
|
||||
sendHeartbeat();
|
||||
heartbeatTimer = Script.setTimeout(onHeartbeatTimer, HEARTBEAT_INTERVAL);
|
||||
}
|
||||
|
||||
function startHeartbeat() {
|
||||
onHeartbeatTimer();
|
||||
}
|
||||
|
||||
function stopHeartbeat() {
|
||||
|
@ -394,7 +466,7 @@
|
|||
switch (message.command) {
|
||||
case PLAYER_COMMAND_PLAY:
|
||||
if (!Player.isPlaying()) {
|
||||
Player.play(message.recording, message.position, message.orientation);
|
||||
Player.play(sender, message.recording, message.position, message.orientation);
|
||||
} else {
|
||||
log("Didn't start playing " + message.recording + " because already playing " + Player.recording());
|
||||
}
|
||||
|
@ -418,7 +490,7 @@
|
|||
Messages.subscribe(HIFI_PLAYER_CHANNEL);
|
||||
|
||||
Player.autoPlay();
|
||||
sendHeartbeat();
|
||||
startHeartbeat();
|
||||
|
||||
UserActivityLogger.logAction("playRecordingAC_script_load");
|
||||
}
|
||||
|
|
|
@ -275,6 +275,7 @@
|
|||
|
||||
Player = (function () {
|
||||
var HIFI_RECORDER_CHANNEL = "HiFi-Recorder-Channel",
|
||||
RECORDER_COMMAND_ERROR = "error",
|
||||
HIFI_PLAYER_CHANNEL = "HiFi-Player-Channel",
|
||||
PLAYER_COMMAND_PLAY = "play",
|
||||
PLAYER_COMMAND_STOP = "stop",
|
||||
|
@ -283,7 +284,6 @@
|
|||
playerIsPlayings = [], // True if AC player script is playing a recording.
|
||||
playerRecordings = [], // Assignment client mappings of recordings being played.
|
||||
playerTimestamps = [], // Timestamps of last heartbeat update from player script.
|
||||
playerStartupTimeouts = [], // Timers that check that recording has started playing.
|
||||
|
||||
updateTimer,
|
||||
UPDATE_INTERVAL = 5000; // Must be > player's HEARTBEAT_INTERVAL.
|
||||
|
@ -304,7 +304,6 @@
|
|||
playerIsPlayings.splice(i, 1);
|
||||
playerRecordings.splice(i, 1);
|
||||
playerTimestamps.splice(i, 1);
|
||||
playerStartupTimeouts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,8 +314,7 @@
|
|||
}
|
||||
|
||||
function playRecording(recording, position, orientation) {
|
||||
var index,
|
||||
CHECK_PLAYING_TIMEOUT = 10000;
|
||||
var index;
|
||||
|
||||
// Optional function parameters.
|
||||
if (position === undefined) {
|
||||
|
@ -340,26 +338,9 @@
|
|||
position: position,
|
||||
orientation: orientation
|
||||
}));
|
||||
|
||||
playerStartupTimeouts[index] = Script.setTimeout(function () {
|
||||
if ((!playerIsPlayings[index] || playerRecordings[index] !== recording) && playerStartupTimeouts[index]) {
|
||||
error("Didn't start playing recording "
|
||||
+ recording.slice(4) + "!"); // Remove leading "atp:" from recording.
|
||||
}
|
||||
playerStartupTimeouts[index] = null;
|
||||
}, CHECK_PLAYING_TIMEOUT);
|
||||
}
|
||||
|
||||
function stopPlayingRecording(playerID) {
|
||||
var index;
|
||||
|
||||
// Cancel check that recording started playing.
|
||||
index = playerIDs.indexOf(playerID);
|
||||
if (index !== -1 && playerStartupTimeouts[index] !== null) {
|
||||
// Cannot clearTimeout() without program log error, so just set null.
|
||||
playerStartupTimeouts[index] = null;
|
||||
}
|
||||
|
||||
Messages.sendMessage(HIFI_PLAYER_CHANNEL, JSON.stringify({
|
||||
player: playerID,
|
||||
command: PLAYER_COMMAND_STOP
|
||||
|
@ -376,15 +357,21 @@
|
|||
|
||||
message = JSON.parse(message);
|
||||
|
||||
index = playerIDs.indexOf(sender);
|
||||
if (index === -1) {
|
||||
index = playerIDs.length;
|
||||
playerIDs[index] = sender;
|
||||
if (message.command === RECORDER_COMMAND_ERROR) {
|
||||
if (message.user === MyAvatar.sessionUUID) {
|
||||
error(message.message);
|
||||
}
|
||||
} else {
|
||||
index = playerIDs.indexOf(sender);
|
||||
if (index === -1) {
|
||||
index = playerIDs.length;
|
||||
playerIDs[index] = sender;
|
||||
}
|
||||
playerIsPlayings[index] = message.playing;
|
||||
playerRecordings[index] = message.recording;
|
||||
playerTimestamps[index] = Date.now();
|
||||
Dialog.updatePlayerDetails(playerIsPlayings, playerRecordings, playerIDs);
|
||||
}
|
||||
playerIsPlayings[index] = message.playing;
|
||||
playerRecordings[index] = message.recording;
|
||||
playerTimestamps[index] = Date.now();
|
||||
Dialog.updatePlayerDetails(playerIsPlayings, playerRecordings, playerIDs);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
@ -392,7 +379,6 @@
|
|||
playerIsPlayings = [];
|
||||
playerRecordings = [];
|
||||
playerTimestamps = [];
|
||||
playerStartupTimeouts = [];
|
||||
Dialog.updatePlayerDetails(playerIsPlayings, playerRecordings, playerIDs);
|
||||
}
|
||||
|
||||
|
@ -529,6 +515,7 @@
|
|||
break;
|
||||
case STOP_PLAYING_RECORDING_ACTION:
|
||||
// Stop the specified player.
|
||||
log("Unload recording " + message.value);
|
||||
Player.stopPlayingRecording(message.value);
|
||||
break;
|
||||
case LOAD_RECORDING_ACTION:
|
||||
|
|
Loading…
Reference in a new issue