Getting Started
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.
_14CC = gcc_14_14ESDK_HOME=path/to/your/esdk/folder_14_14CFLAGS = -g -Wall -I$(ESDK_HOME)/include_14LDFLAGS = -lm $(ESDK_HOME)/lib/libspotify_embedded_static.a_14_14all: main_14_14main: main.o_14main.o: main.c_14_14clean:_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_50static void CallbackError(SpError error, void *context) {_50 printf("Error: %d\n", error);_50}_50 _50int 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:
_10make 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:
_61SpError error_occurred = kSpErrorOk;_61_61static void CallbackError(SpError err, void *context) {_61 LOG("Error: %d\n", err);_61 error_occurred = err;_61}_61_61int 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_61end:_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.