2

libspotifyをラップするnodeJS用のモジュールを作成しようとしています。目標は、spotifyから音楽を再生するデバイスのリモートコントロールを可能にするWebアプリを作成することです。

スレッドの安全性を確保するためにspshellの例に沿って進み、すべてのAPI関数を呼び出す個別のスレッドを開始するプレーンCで「Spotifyサービス」を作成することにしました。

次に、nodeJSモジュールは、提供されているいくつかの関数を呼び出して、spotifyと対話します。サービスのコードはここにあります:http://pastebin.com/KB6uwSC8新しいスレッドは下部から開始されます。

さて、私がこのような単純なプログラムでこれを呼び出すと(fgetはログインを完了するための簡単な方法を持っているだけです)。私はc++を使用して、node-gypがコードをコンパイルするのと同じくらい近づきました。

#include <stdio.h>

extern "C" {
        #include "objects/SpotifyService.h"
}

int  main(int argc, char** argv) {
    login();
    char string[100];
    fgets(string, 100, stdin);
    fprintf(stdout, "Got: %s", string);
    logout();
    fgets(string, 100, stdin);
    fprintf(stdout, "Got: %s", string);
    return 0;
}

正常に動作します。これをクラッシュさせることはできません。

nodeJSでまったく同じ「サービス」を使用すると(つまり、呼び出しlogin()logout()他に何もしない)、ログアウト時に7〜8/10回のようにクラッシュすることがあります。私は次のようなたくさんのことを試しました:

  • node-gypから私の小さな例へのコンパイラフラグのコピー
  • Spotifyスレッドのスレッド属性をいじる
  • OSXとDebianでのコンパイル
  • プレーンなpthreadの代わりにlibuvを使用する
  • 私の「サービス」を共有ライブラリにコンパイルし、ノードからこれを呼び出します

無駄に。クラッシュするだけです。gdb内から呼び出された場合、クラッシュは少ないようですが、ランダムである可能性があります。

gdbからのスタックトレースは次のことを示しています。

Thread 3 (Thread 0x7ffff65fd700 (LWP 21838)):
#0  0x00007ffff678f746 in ?? () from /usr/local/lib/libspotify.so.12
#1  0x00007ffff6702289 in ?? () from /usr/local/lib/libspotify.so.12
#2  0x00007ffff6702535 in ?? () from /usr/local/lib/libspotify.so.12
#3  0x00007ffff6703b5a in ?? () from /usr/local/lib/libspotify.so.12
#4  0x00007ffff6703c86 in ?? () from /usr/local/lib/libspotify.so.12
#5  0x00007ffff66c5c8b in ?? () from /usr/local/lib/libspotify.so.12
#6  0x00007ffff679a5b3 in sp_session_process_events () from /usr/local/lib/libspotify.so.12
#7  0x00007ffff6aa7839 in spotifyLoop (nervNicht=<value optimized out>) at    ../src/SpotifyService.c:103
#8  0x00007ffff70118ca in start_thread () from /lib/libpthread.so.0
#9  0x00007ffff6d78b6d in clone () from /lib/libc.so.6
#10 0x0000000000000000 in ?? ()

(OSXでは、gdbは、libspotifyで呼び出される関数が「process_title」と呼ばれることを示しました。)

これまでのところ何も役に立たなかったので、これを機能させることができるかどうか、またはそれがnodeJSと互換性がないlibspotifyの何かであるかどうかはわかりません。node-gypが.oファイルをリンクする方法がわかりません。何か問題が発生している可能性がありますか?

これを行おうとする他の2つのプロジェクトをgithubで見つけましたが、そのうちの1つは実際にSpotifyメインループをJavascriptに配置し、もう1つはノード0.1.100とlibspotify 0.0.4を使用しており、2年間更新されていません。どちらからも何も学べませんでした。

4

1 に答える 1

1

わかりました、もう少し遊んでみました。ログアウト エラーを無視して、他の機能の実装を続けました。

Logged_in コールバックに新しい sp_playlist_container の作成を追加しましたが、明らかにそれが役に立ちました。その後、ノード モジュールはもうクラッシュしません (またはまだクラッシュしていません)。

static sp_playlistcontainer_callbacks pc_callbacks = {
     .container_loaded = &rootPlaylistContainerLoaded,
};

static void rootPlaylistContainerLoaded(sp_playlistcontainer* pc, void* userdata) {
    int numPlaylists = sp_playlistcontainer_num_playlists(pc);
    fprintf(stdout, "Root playlist synchronized, number of Playlists: %d\n", numPlaylists);
}

static void loggedIn(sp_session* session, sp_error error) {
    if(SP_ERROR_OK != error) {
            fprintf(stderr, "Error logging in: %s\n", sp_error_message(error));
    } else {
            fprintf(stdout, "Service is logged in!\n");
    } 

    //This is absolutely necessary here, otherwise following callbacks can crash.
    sp_playlistcontainer *pc = sp_session_playlistcontainer(spotifySession);
    sp_playlistcontainer_add_callbacks(pc, &pc_callbacks, NULL);
}  

しかし、sp_playlist_container の作成は、logged_in コールバックで行う必要があります。別の関数 (「getPlaylistNames」など) でそれを呼び出すと、プログラムもクラッシュしました。

それが引き続き機能するかどうかを確認し、この回答が他の人に役立つことを願っています.

于 2013-02-03T14:29:24.453 に答える