278 lines · 8.5 KB · JavaScript
RawDownload
"use strict"; ////  EZrecord.js////  Created by David Rowe on June 24th, 2017.//  Copyright 2017 High Fidelity, Inc.//  Copyright 2023 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// (function () {     var APP_NAME = "EZRECORD",        APP_ICON_INACTIVE = "icons/tablet-icons/avatar-record-i.svg",        APP_ICON_ACTIVE = "icons/tablet-icons/avatar-record-a.svg",        SHORTCUT_KEY = "r",  // Alt modifier is assumed.        tablet,        button,         RecordingIndicator,        Recorder;     function log(message) {        print(APP_NAME + ": " + message);    }     function logDetails() {        return {            current_domain: location.placename        };    }     RecordingIndicator = (function () {        // Displays "recording" overlay.         var hmdOverlay,            HMD_FONT_SIZE = 0.08,            desktopOverlay,            DESKTOP_FONT_SIZE = 24;         function show() {            // Create both overlays in case user switches desktop/HMD mode.            var screenSize = Controller.getViewportDimensions(),                recordingText = "REC",  // Unicode circle \u25cf doesn't render in HMD.                CAMERA_JOINT_INDEX = -7;             if (HMD.active) {                // 3D overlay attached to avatar.                hmdOverlay = Entities.addEntity({                    "type": "Text",                    "text": recordingText,                    "dimensions": { "x": 3 * HMD_FONT_SIZE, "y": HMD_FONT_SIZE, "z": 0.01 },                    "parentID": MyAvatar.sessionUUID,                    "parentJointIndex": CAMERA_JOINT_INDEX,                    "localPosition": { "x": 0.95, "y": 0.95, "z": -2.0 },                    "color": { "red": 255, "green": 0, "blue": 0 },                    "alpha": 0.9,                    "unlit": true,                    "lineHeight": HMD_FONT_SIZE,                    "backgroundAlpha": 0,                    "ignorePickIntersection": true,                    "billboardMode": "full",                    "renderLayer": "front",                    "visible": true                },"local");            } else {                // 2D overlay on desktop.                desktopOverlay = Overlays.addOverlay("text", {                    text: recordingText,                    width: 3 * DESKTOP_FONT_SIZE,                    height: DESKTOP_FONT_SIZE,                    x: screenSize.x - 4 * DESKTOP_FONT_SIZE,                    y: DESKTOP_FONT_SIZE,                    font: { size: DESKTOP_FONT_SIZE },                    color: { red: 255, green: 8, blue: 8 },                    alpha: 1.0,                    backgroundAlpha: 0,                    visible: true                });            }        }         function hide() {            if (desktopOverlay) {                Overlays.deleteOverlay(desktopOverlay);            }            if (hmdOverlay) {                Entities.deleteEntity(hmdOverlay);            }        }         return {            show: show,            hide: hide        };    }());     Recorder = (function () {        var IDLE = 0,            COUNTING_DOWN = 1,            RECORDING = 2,            recordingState = IDLE,             countdownTimer,            countdownSeconds,            COUNTDOWN_SECONDS = 3,             tickSound,            startRecordingSound,            finishRecordingSound,            TICK_SOUND = "../system/assets/sounds/countdown-tick.wav",            START_RECORDING_SOUND = "../system/assets/sounds/start-recording.wav",            FINISH_RECORDING_SOUND = "../system/assets/sounds/finish-recording.wav",            START_RECORDING_SOUND_DURATION = 1200,            SOUND_VOLUME = 0.2;         function playSound(sound) {            Audio.playSound(sound, {                position: MyAvatar.position,                localOnly: true,                volume: SOUND_VOLUME            });        }         function isRecording() {            return recordingState === COUNTING_DOWN || recordingState === RECORDING;        }         function startRecording() {            if (recordingState !== IDLE) {                return;            }             log("Start countdown");            countdownSeconds = COUNTDOWN_SECONDS;            playSound(tickSound);            countdownTimer = Script.setInterval(function () {                countdownSeconds -= 1;                if (countdownSeconds <= 0) {                    Script.clearInterval(countdownTimer);                    playSound(startRecordingSound);                    log("Start recording");                    Script.setTimeout(function () {                        // Delay start so that start beep is not included in recorded sound.                        Recording.startRecording();                        RecordingIndicator.show();                    }, START_RECORDING_SOUND_DURATION);                    recordingState = RECORDING;                } else {                    playSound(tickSound);                }            }, 1000);             recordingState = COUNTING_DOWN;        }         function cancelRecording() {            log("Cancel recording");            if (recordingState === COUNTING_DOWN) {                Script.clearInterval(countdownTimer);            } else {                Recording.stopRecording();                RecordingIndicator.hide();            }            recordingState = IDLE;        }         function finishRecording() {            playSound(finishRecordingSound);            Recording.stopRecording();            RecordingIndicator.hide();            var filename = (new Date()).toISOString();  // yyyy-mm-ddThh:mm:ss.sssZ            filename = filename.replace(/[\-:]|\.\d*Z$/g, "").replace("T", "-") + ".hfr";  // yyyymmmdd-hhmmss.hfr            filename = Recording.getDefaultRecordingSaveDirectory() + filename;            log("Finish recording: " + filename);            Recording.saveRecording(filename);            recordingState = IDLE;            UserActivityLogger.logAction("ezrecord_finish_recording", logDetails());        }         function stopRecording() {            if (recordingState === COUNTING_DOWN) {                cancelRecording();            } else if (recordingState === RECORDING) {                finishRecording();            }        }         function setUp() {            tickSound = SoundCache.getSound(Script.resolvePath(TICK_SOUND));            startRecordingSound = SoundCache.getSound(Script.resolvePath(START_RECORDING_SOUND));            finishRecordingSound = SoundCache.getSound(Script.resolvePath(FINISH_RECORDING_SOUND));        }         function tearDown() {            if (recordingState !== IDLE) {                cancelRecording();            }        }         return {            isRecording: isRecording,            startRecording: startRecording,            stopRecording: stopRecording,            setUp: setUp,            tearDown: tearDown        };    }());     function toggleRecording() {        if (Recorder.isRecording()) {            Recorder.stopRecording();        } else {            Recorder.startRecording();        }        button.editProperties({ isActive: Recorder.isRecording() });    }     function onKeyPressEvent(event) {        if (event.isAlt && event.text === SHORTCUT_KEY && !event.isControl && !event.isMeta && !event.isAutoRepeat) {            toggleRecording();        }    }     function onButtonClicked() {        toggleRecording();    }     function setUp() {        tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");        if (!tablet) {            return;        }         Recorder.setUp();         // tablet/toolbar button.        button = tablet.addButton({            icon: APP_ICON_INACTIVE,            activeIcon: APP_ICON_ACTIVE,            text: APP_NAME,            isActive: false        });        if (button) {            button.clicked.connect(onButtonClicked);        }         Controller.keyPressEvent.connect(onKeyPressEvent);         UserActivityLogger.logAction("ezrecord_run_script", logDetails());    }     function tearDown() {         Controller.keyPressEvent.disconnect(onKeyPressEvent);         Recorder.tearDown();         if (!tablet) {            return;        }         if (button) {            button.clicked.disconnect(onButtonClicked);            tablet.removeButton(button);            button = null;        }         tablet = null;     }     setUp();    Script.scriptEnding.connect(tearDown);}());