Lens Scripting API
    Preparing search index...

    Class VideoRecorder

    Allows you to record a new texture (i.e video), based on on another texture.

    Returned By: VideoRecorder.create

    // @input Component.Image displayImage

    let target = requireAsset("./Render Target.renderTarget");
    let recorder = null;
    let isRecording = false;
    let isProcessingStop = false;

    // Function to validate components
    function validateComponents() {
    print("=== Component Validation ===");

    if (!target) {
    print("ERROR: Render Target asset is null or undefined");
    return false;
    }
    print("✓ Render Target asset loaded");

    if (!script.displayImage) {
    print("ERROR: displayImage component is not assigned in Inspector");
    return false;
    }
    print("✓ displayImage component found");

    if (!script.displayImage.mainMaterial) {
    print("ERROR: displayImage.mainMaterial is null");
    return false;
    }
    print("✓ displayImage.mainMaterial found");

    if (!script.displayImage.mainMaterial.mainPass) {
    print("ERROR: displayImage.mainMaterial.mainPass is null");
    return false;
    }
    print("✓ displayImage.mainMaterial.mainPass found");

    print("=== All components validated successfully ===");
    return true;
    }

    // Function to cleanup and reset recorder
    function cleanupRecorder() {
    try {
    if (recorder) {
    // Cancel any ongoing recording
    if (isRecording) {
    recorder.cancelRecording();
    print("Recording cancelled during cleanup");
    }
    recorder = null;
    }
    isRecording = false;
    isProcessingStop = false;
    print("Recorder cleaned up successfully");
    } catch (error) {
    print("Error during cleanup: " + error);
    }
    }

    // Function to initialize VideoRecorder
    function initializeRecorder() {
    try {
    // Clean up any existing recorder first
    cleanupRecorder();

    if (!validateComponents()) {
    print("ERROR: Component validation failed - cannot initialize VideoRecorder");
    return false;
    }

    // Set up a new VideoRecorder instance
    const options = new VideoRecorder.Options(target);
    options.saveThumbnail = true;
    recorder = VideoRecorder.create(options);
    print("VideoRecorder initialized successfully");
    return true;
    } catch (error) {
    print("Error initializing VideoRecorder: " + error);
    cleanupRecorder();
    return false;
    }
    }

    // Initialize the recorder
    if (!initializeRecorder()) {
    print("FATAL: Cannot initialize VideoRecorder - script will not function");
    }

    // Start recording
    script.createEvent("TouchStartEvent").bind(function(eventData) {
    if (!recorder) {
    print("VideoRecorder not initialized - attempting to reinitialize");
    if (!initializeRecorder()) {
    print("Failed to reinitialize VideoRecorder");
    return;
    }
    }

    if (isRecording) {
    print("Already recording, ignoring start request");
    return;
    }

    if (isProcessingStop) {
    print("Still processing previous stop, ignoring start request");
    return;
    }

    try {
    recorder.startRecording();
    isRecording = true;
    print("Recording started");
    } catch (error) {
    print("Error starting recording: " + error);
    isRecording = false;
    }
    });

    // Stop recording and display the result
    script.createEvent("TouchEndEvent").bind(function(eventData) {
    if (!recorder) {
    print("VideoRecorder not initialized");
    return;
    }

    if (!isRecording) {
    print("Not recording, ignoring stop request");
    return;
    }

    if (isProcessingStop) {
    print("Already processing stop, ignoring request");
    return;
    }

    try {
    print("Attempting to stop recording...");
    isProcessingStop = true;

    // Fixed: properly handle the Promise returned by stopRecording()
    recorder.stopRecording().then(function(texture) {
    print("stopRecording() promise resolved");

    // Debug the texture
    if (!texture) {
    print("ERROR: stopRecording() returned null/undefined texture");
    print("This might indicate the recording was too short or failed");
    isRecording = false;
    isProcessingStop = false;
    return;
    }

    print("✓ Texture received from stopRecording()");
    print("Texture type: " + typeof texture);

    // Re-validate components before assignment
    if (!script.displayImage) {
    print("ERROR: displayImage component is null during assignment");
    isRecording = false;
    isProcessingStop = false;
    return;
    }

    if (!script.displayImage.mainMaterial) {
    print("ERROR: displayImage.mainMaterial is null during assignment");
    isRecording = false;
    isProcessingStop = false;
    return;
    }

    if (!script.displayImage.mainMaterial.mainPass) {
    print("ERROR: displayImage.mainMaterial.mainPass is null during assignment");
    isRecording = false;
    isProcessingStop = false;
    return;
    }

    // Try to assign the texture
    try {
    script.displayImage.mainMaterial.mainPass.baseTex = texture;
    print("✓ Recording stopped and texture assigned successfully");
    } catch (assignError) {
    print("ERROR: Failed to assign texture: " + assignError);
    }

    // Reset state
    isRecording = false;
    isProcessingStop = false;

    // Clean up and reinitialize for next recording
    cleanupRecorder();
    if (!initializeRecorder()) {
    print("WARNING: Failed to reinitialize recorder for next use");
    }

    }).catch(function(error) {
    print("ERROR: stopRecording() promise rejected: " + error);
    isRecording = false;
    isProcessingStop = false;

    // Clean up and reinitialize on error
    cleanupRecorder();
    if (!initializeRecorder()) {
    print("WARNING: Failed to reinitialize recorder after error");
    }
    });

    } catch (error) {
    print("Error in stop recording process: " + error);
    isRecording = false;
    isProcessingStop = false;

    // Clean up and reinitialize on error
    cleanupRecorder();
    if (!initializeRecorder()) {
    print("WARNING: Failed to reinitialize recorder after error");
    }
    }
    });

    Hierarchy (View Summary)

    Index

    Methods

    • Cancels any ongoing recording and discards what has been recorded so far.

      Returns void

    • Returns true if the object matches or derives from the passed in type.

      Parameters

      • type: string

      Returns boolean

    • Returns true if this object is the same as other. Useful for checking if two references point to the same thing.

      Parameters

      Returns boolean

    • Starts to record the target texture on the next frame.

      Returns void

    • Stops recording and returns a Promise which will be fulfilled with a Texture containing a VideoTextureProvider that is the recorded data.

      Returns Promise<Texture>