Clone track (Headless)

Tutorial: Creating the Clone Track Extension

This tutorial shows how to create an extension called clone-track that allows duplicating audio tracks in Moises. We'll follow a complete step-by-step process from creation to publication.

Step 1: Creating the Extension

First, run the command to create a new extension from the official boilerplate:

npm create @moises.ai/extension clone-track

This command will:

  • Create a new clone-track folder
  • Install all necessary dependencies
  • Set up the basic extension structure

Step 2: Configuring the Extension

Navigate to the extension folder and open the app/clone-track/page.js to configure initMoisesExtension:

import { initMoisesExtension } from '@moises.ai/extension';

const useMoisesExtension = initMoisesExtension({
  id: 'clone-track',
  name: 'Clone Track',
  description: 'Clone selected audio tracks',
  icon: '🎵',
  version: '1.0.0',
  author: 'Your Name'
});

Step 3: Implementing the Functionality

Accessing the Moises API

Now let's use the useMoisesExtension hook to access the Moises API. The hook returns two important properties:

  • moises: This is where the API is located with all available methods. You can find the complete reference of all available methods in the API Reference documentation.
  • isConnected: This property is used to verify if the extension has successfully connected to the extension server.
export default function Page() {
  const { moises, isConnected } = useMoisesExtension();

  return null
}

Important Note: This function returns null because this is a headless extension that has no UI - it only provides functionality. Headless extensions work in the background and don't render any visual interface.

We need to use useEffect to make the connection call. This ensures the link is established when the component mounts and the extension is properly connected:

"use client";

import { useEffect } from "react";
import { initMoisesExtension } from "@moises.ai/extension";

const useMoisesExtension = initMoisesExtension({
  id: "clone-track",
  name: "Clone Track",
  description: "Clone selected audio tracks",
  version: "1.0.0",
  author: "You name goes here"
});

export default function Page() {
  const { moises, isConnected } = useMoisesExtension();

  useEffect(() => {
    // First, we must check if isConnected is true before making any API calls
    if (!isConnected) return;

    // Use the new moises.link.trackContextMenu method to add items to track context menu
    moises.link.trackContextMenu({ label: "Clone track" }, async ({ trackId }) => {
      // Get the track data using the track ID
      const track = await moises.track.get({ trackId });
      
      // Create a new track using the original track's data
      await moises.track.create({ 
        arrayBuffer: track.arrayBuffer, 
        name: `Clone of ${track.name}` 
      });
    })
  }, [moises, isConnected]);

  return null
}

The moises.link method is used to connect your extension with the DAW interface. The new API uses specific methods for each type of mount point:

moises.link.trackContextMenu

This specific method is used to add items to the track context menu. It takes two parameters:

  1. First Parameter - Configuration: An object containing the label and other configuration options for the UI element. In this case, { label: "Clone track" } sets the text that will appear in the context menu.

  2. Second Parameter - Callback Function: This is the function that will be executed when the user interacts with your extension element. It receives context data (like trackId in this example) that you can use in your implementation.

Syntax:

moises.link.trackContextMenu(config, callback)

Example:

moises.link.trackContextMenu({ label: "Clone track" }, async ({ trackId }) => {
  // Your logic here
});

Other Available Mount Points

The new moises.link API offers specific methods for different mount points in the application:

  • moises.link.footerButton()
  • moises.link.toolbarButton()

And other specific methods for each interface location

Each method follows the same pattern: first parameter for configuration and second parameter for the callback function.

API Methods Explained

The example uses two important API methods from the Moises API. You can find all available methods in the API Reference:

  • moises.track.get({ trackId }): This method retrieves the track data corresponding to the provided ID. It returns a track object containing all the track information including the audio buffer, name, position, and other properties.

  • moises.track.create({ arrayBuffer, name }): This method creates a new track using the provided parameters. In this example, we're using the arrayBuffer from the original track (which contains the audio data) and setting a new name with "(Cloned)" appended to it.

Complete Implementation

Here's the complete implementation with proper imports and structure:

"use client";

import { useEffect } from "react";
import { initMoisesExtension } from "@moises.ai/extension";

const useMoisesExtension = initMoisesExtension({
  id: "clone-track",
  name: "Clone Track",
  description: "Clone selected audio tracks",
  version: "1.0.0",
  author: "You name goes here"
});

export default function Page() {
  const { moises, isConnected } = useMoisesExtension();

  useEffect(() => {
    // First, we must check if isConnected is true before making any API calls
    if (!isConnected) return;

    // Use the new moises.link.trackContextMenu method to add items to track context menu
    moises.link.trackContextMenu({ label: "Clone track" }, async ({ trackId }) => {
      // Get the track data using the track ID
      const track = await moises.track.get({ trackId });
      
      // Create a new track using the original track's data
      await moises.track.create({ 
        arrayBuffer: track.arrayBuffer, 
        name: `Clone of ${track.name}` 
      });
    })
  }, [moises, isConnected]);

  return null
}

Step 4: Testing the Extension

Now you can test your extension in the Moises Studio:

  1. Go to studio.moises.ai/app
  2. Create a new project
  3. Open the context menu and select "Manage Extensions"
  4. Install your local extension using: http://localhost:3000/clone-track

Additional Resources