Moo
Moo - a media cloud collaboration SDK

Introduction

Welcome to the Moo SDK. Moo (short for 'MooSinc') provides a library and header files for programmers to support media online collaboration of the Moo Network.

The Moo SDK currently supports

  • Windows
  • macOS
  • iOS
  • AppleTV

Moo SDK provides a simple and compact interface to

  • login and manage a user
  • search and connect with other users ('friends')
  • create or join and share media projects and files
  • messaging between project members and friends

The Moo SDK does not provide

  • any user interface actions
  • any media playback or recording (engine)
  • conversion of existing DAW project formats. These may be available elsewhere though.

Installation

To load the library, create an instance of MooLibLoader and have it create the Moo object. From there, you can access Moo's modules. Follow their respective documentations

Moo makes it easy for DAW or similar software developers to import and export relevant resources independant from vendor or formats. This way, users of various software application can exchange content, information, and messages. Data are stored in the cloud and are accessible anywhere and at any time, provided an internet connection.

Overview

Moo is organized into the following main categories exposed as C++ classes which can be obtained from the moo object:

  • MooUser
    • login, logout, account info, manage paid resources etc
  • MooFriends
    • search and manage friends, which are of class *MooFriend
    • profile information generated with the MooUser interface
    • invite, confirm invitation
    • messaging (online and offline)
  • MooProjects
    • create and join projects which are of class *MooProject
    • add tracks, clips, and media files
    • sync projects to provide your changes and get other members' changes
    • messaging between project members

Samples

Check the Qt sample provided with the SDK which demonstrates all of the main functionality with very compact and easy to follow code. It should be easy to derive from there if you don't want to use Qt.

As for a teaser, this simple code snippet will create a project, invite a friend and place an audio file at 0:0 : 4 : 0 (all project times are in seconds) :

// create a new project
mooUInt mooProjectID = mooProjects->createProject ();
if (mooProjectID > 0)
{
// open the project
mooInt success = mooProjects->openProject (mooProjectID);
if (success == MOO_OK)
{
// get the project object
MooProject* mooProject = mooProjects->getProject (mooProjectID);
if (mooProject)
{
// have ourselves notified of changes to the project
mooProject->addCallback (myProjectCallback, myDAW);
// get the user folder
MooTrack* userFolder = mooProject->getUserFolder ();
if (userFolder)
{
// add some audio
// MooProjects will also invoke your callback with kProjectTrackAdded
MooTrack* track = userFolder->addTrack (MooMediaTypeAudio);
if (track)
{
// add a clip to the track
MooClip* clip = track->addClip ();
if (clip)
{
// add an existing local audio file to the clip
MooInt64 success = clip->setMediaFile ("test.wav");
clip->move (4.);
}
}
}
mooProject->sync ();
// invite a friend. friend will get a message and can load project
MooFriend* myFriend = getMyFriend ();
if (myFriend)
mooProject->invite (myFriend->id ());
}
}
}

We can now obtain lists of folders and tracks. For instance, you should update your project after each MooProject sync opertion:

void myProjectCallback (MooProject* project, MooInt64 operation, void* myRefence)
{
MyDAW* myDAW = (MyDAW*)myReference;
switch (operation)
{
case MooProject::kProjectChanged:
{
MooTrack* root = project->getRootTrack ();
if (root)
{
mooInt numFolders = 0;
MooTrack** folders = root->getTracks (numFolders);
for (int f = 0; f < numFolders; f++)
{
MooTrack* mooFolder = folders[f];
// note: due to the dynamic nature of cloud operations, every object in Moo object lists of the form MoXXX** may be NULL!
if (mooFolder)
{
mooInt numTracks = 0;
MooTrack** tracks = mooFolder->getTracks (numTracks);
for (int t = 0; t < numTracks; t++)
{
MooTrack* track = tracks[t];
if (track)
{
// do something with the track
myDAW->updateTrack (track);
mooInt numClips = 0;
MooClip** clips = track->getClips (numClips);
for (int c = 0; c < numClips; c++)
{
// do something with the clip (getMediaFileName ()...)
MooClip* clip = clips[c];
if (clip)
myDAW->updateClip (track, clip);
}
}
}
}
}
}
}
}
}

Please note that because of the dynamic nature of cloud based projects, you should not store id lists or pointers to media objects such as tracks or clips for later reference, but obtain such information anew whenever needed.Also note that callbacks such as the aforementioned are asynchronous; that is, when you call mooProject->sync (), nothing may happen at this point but myCallback may be called at some later point in time, so you should take care avoiding deadlocks, even though callbacks are invoked only in the user thread.