Skip to content

Getting Started

Warning:Commercial Hardware tools and the eSDK are available only for approved partners

This section shows you how to use the Spotify eSDK to write a simple Spotify Connect-enabled music player application.

The Spotify eSDK is a lightweight library with a C API that allows you to integrate Spotify into your devices and applications. It has been written from the ground up with the needs of device manufacturers in mind. The SDK provides an API that facilitates the integration and ensures high performance and low memory footprint on a wide range of hardware architectures.

Set up the environment

The first steps is to download an eSDK build from Certomato under the Builds section. Please refer to the Onboarding section if you don't have access to Certomato access yet.

Once you have the eSDK bundle locally stored, unzip it. A new folder will be created with the following contents:

  • docs folder which contains the API Reference in HTML format.
  • examples with file samples using the eSDK in different contexts.
  • include with headers file for compiling.
  • libs which contains a static and dynamic version of the eSDK library ready to be linked with.

The next step is to generate a valid client_id. Please follow the app guide to do so.

Let's create our workspace that will store our project. Create a new folder called esdk-hello-world and add a file called Makefile.

A Makefile is a file which defines a set of rules (compile, link, clean, etc.) to be executed by the make tool. There are other tools you could use to build your sofrware software, such as cmake or scons, but we will use make for the sake of simplicity.


_14
CC = gcc
_14
_14
ESDK_HOME=path/to/your/esdk/folder
_14
_14
CFLAGS = -g -Wall -I$(ESDK_HOME)/include
_14
LDFLAGS = -lm $(ESDK_HOME)/lib/libspotify_embedded_static.a
_14
_14
all: main
_14
_14
main: main.o
_14
main.o: main.c
_14
_14
clean:
_14
rm -rvf main.o main

Don't forget to replace the ESDK_HOME variable with the location of the unzipped eSDK folder.

Initializing the library

Create a new file called main.c with the following content, which contains a simplified example of using the SpInit() function:


_50
#include <stdio.h>
_50
#include <unistd.h>
_50
#include <sys/time.h>
_50
#include <stdlib.h>
_50
#include <string.h>
_50
#include <ctype.h>
_50
#include <signal.h>
_50
#include "latest"
_50
#include "spotify_embedded_log.h"
_50
_50
static void CallbackError(SpError error, void *context) {
_50
printf("Error: %d\n", error);
_50
}
_50
_50
int main(int argc, char *argv[]) {
_50
SpError err;
_50
struct SpConfig conf;
_50
int buffer_size = SP_RECOMMENDED_MEMORY_BLOCK_SIZE;
_50
enum SpDeviceType device_type = kSpDeviceTypeSpeaker;
_50
const char *client_id = "my-client-id";
_50
_50
memset(&conf, 0, sizeof(conf));
_50
_50
conf.api_version = SP_API_VERSION;
_50
conf.memory_block = malloc(buffer_size);
_50
conf.memory_block_size = buffer_size;
_50
conf.error_callback = CallbackError;
_50
conf.error_callback_context = NULL;
_50
conf.display_name = "Example";
_50
conf.unique_id = "my-sample-unique-id";
_50
conf.brand_name = "Example_Brand";
_50
conf.model_name = "example_embedded";
_50
conf.brand_display_name = "Example Brand";
_50
conf.model_display_name = "example_embedded \u266C";
_50
conf.device_type = device_type;
_50
conf.zeroconf_serve = 1;
_50
conf.zeroconf_port = 0;
_50
conf.host_name = conf.unique_id;
_50
conf.client_id = client_id;
_50
conf.scope = SP_SCOPE_STREAMING;
_50
_50
if (kSpErrorOk != (err = SpInit(&conf))) {
_50
printf("Error %d\n", err);
_50
return 0;
_50
}
_50
_50
SpFree();
_50
_50
return 0;
_50
}

The example calls the function SpInit() to perform the eSDK initialization. The function takes a struct of type SpConfig as a parameter.

Finally, compile and generate the binary with the following command:


_10
make all

Adding a main event loop

In order to implement the main event loop, the function SpPumpEvents() must be called periodically. To show how this works, let's force a login error by calling the function SpConnectionLoginOauthToken() with an invalid token. After calling SpPumpEvents() a couple of times, the error callback will be invoked and the application quits.

Here is the new code that checks for login errors:


_61
SpError error_occurred = kSpErrorOk;
_61
_61
static void CallbackError(SpError err, void *context) {
_61
LOG("Error: %d\n", err);
_61
error_occurred = err;
_61
}
_61
_61
int main(int argc, char *argv[]) {
_61
SpError err;
_61
struct SpConfig conf;
_61
int buffer_size = SP_RECOMMENDED_MEMORY_BLOCK_SIZE;
_61
enum SpDeviceType device_type = kSpDeviceTypeSpeaker;
_61
const char *client_id = "my-client-id";
_61
_61
memset(&conf, 0, sizeof(conf));
_61
_61
conf.api_version = SP_API_VERSION;
_61
conf.memory_block = malloc(buffer_size);
_61
conf.memory_block_size = buffer_size;
_61
conf.error_callback = CallbackError;
_61
conf.error_callback_context = NULL;
_61
conf.display_name = "Example";
_61
conf.unique_id = "my-sample-unique-id";
_61
conf.brand_name = "Example_Brand";
_61
conf.model_name = "example_embedded";
_61
conf.brand_display_name = "Example Brand";
_61
conf.model_display_name = "example_embedded \u266C";
_61
conf.device_type = device_type;
_61
conf.zeroconf_serve = 1;
_61
conf.zeroconf_port = 0;
_61
conf.host_name = conf.unique_id;
_61
conf.client_id = client_id;
_61
conf.scope = SP_SCOPE_STREAMING;
_61
_61
if (kSpErrorOk != (err = SpInit(&conf)))
_61
LOG("Error %d\n", err);
_61
goto end;
_61
}
_61
_61
err = SpConnectionLoginOauthToken("this is not a real OAuth access token");
_61
if (err != kSpErrorOk) {
_61
/* The function would only return an error if we hadn't invoked SpInit()
_61
or if we had passed an empty username or password.
_61
Actual login errors will be reported to ErrorCallback().
_61
*/
_61
LOG("Error %d\n", err);
_61
goto end;
_61
}
_61
_61
while (1) {
_61
err = SpPumpEvents();
_61
if (kSpErrorOk != err || error_occurred) {
_61
goto end;
_61
}
_61
}
_61
_61
end:
_61
SpFree();
_61
_61
return 0;
_61
}

What's next?

You can follow the eSDK Developer Guides to read further about how to integrate the eSDK.