Flutter で Nas 音楽プレーヤーを作成する (1)
ここ 2 か月間退屈していたので、家にある古い NAS をいじって [音楽サーバーをセットアップ](https://www.igerm.ee/ experience/%E7%AE%A1%) しています。 ですが、特に満足のいくプレイヤーが見つからないというのもあります。デスクトップの Sonixd は見た目も良く、派手な機能もありませんが、モバイル版は substreamer だけがあまり満足のいくものではありません、も使えますが、あまり美しくありません。
最も重要なことは、これら 2 つのプレーヤーは歌詞をサポートしておらず、あいまい検索や簡略化された従来の検索を実行できないことです。たとえば、ジェイ・チョウの退后を聴きたいのですが、検索で表示される名前は 退後 です。検索すると、繁体字中国語に切り替える必要があります。かなり迷惑です。
私の最初の反応は、既製のマルチターミナル ホイールがあるかどうかを確認するために Github に行くことでした。しかし、私が見ることができるものはすべてローカルで再生されているか、NetEase Cloud の API を通じて構築された模造 NetEase Cloud 音楽プレーヤーが存在していました。切断はもちろん、Navidrome や Subsonic API もサポートしていません。なかなか見つからないので、頑張って自分で手に入れてみます!
Subsonic API
Navidrome 自体にはネイティブ API がありますが、多くはありません。幸いなことに、作者は Subsonic の API をほぼすべてサポートしているため、Navidrome 自体に API ドキュメントがない場合でも、Subsonic のドキュメントは Postman でも試すことができます。
検証サーバー

一見するとわかりにくいように思えるかもしれませんが、実際には非常に単純な 2 種類の検証があります。パスワード を渡すか、暗号化された (パスワード + 6 Salt値) に 6 Salt値 を加えたものを渡します
まず、テストするサーバーにPingを実行します (dio: ^4.0.6 を使用すると、多くの操作を節約できます)
1 try {
2 var response = await Dio().get(
3 _baseUrl +
4 'rest/ping?v=0.0.1&c=xiumusic&f=json&u=' +
5 _username + //v はクライアントのバージョン番号、c はクライアントの名前、u はユーザー名、p はパスワードです
6 '&p=' +
7 _password,
8 );
9 print(response);
10 if (response.statusCode == 200) {
11 //ここでもう 1 つのステップを実行する必要があります。つまり、code200 が返されても満足せず、subsonicサーバーからのフィードバックを確認します。
12 Map _value = response.data['subsonic-response'];
13 String _status = _value['status'];
14 //通常は問題ありません、私は自給自足です、自己デバッグ中です、アップグレードするときはこの状況を認める必要があります、わかりません、わかりません。
15 if (_status == 'failed') {
16 return false;
17 } else {
18 return true;
19 }
20 } else {
21 return false;
22 }
23 } catch (e) {
24 print(e);
25 return false;
26 }
2 段階認証サーバーと Subsonic の API が完了したら、後続のすべての API でその値を取得するために Salt を使用できます。これらはすべて無料です。
暗号化されたログイン
Rondomを使用して、ランダムに生成された 6 桁の文字を書き込みます
1String generateRandomString() {
2 final _random = Random();
3 const _availableChars =
4 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
5 final randomString = List.generate(6,
6 (index) => _availableChars[_random.nextInt(_availableChars.length)])
7 .join();
8
9 return randomString;
10}
- スプライシング後に MD5 暗号化を使用します。
後で API で使用するためにこれらの 2 文字を保存します。
ディレクトリの取得
Subsonic のディレクトリは上から下にこのように分類されます
- 音楽フォルダー
- アーティストフォルダー
- アルバム
- 曲
ただし、Navidrome には音楽フォルダーが 1 つしかないようなので、第 2 レベルの getIndexes を直接使用してディレクトリ マスター リストを作成し、その後 ミュージシャン ID に基づいてアルバム リストに進みました。

音楽を再生
変更量を変更するには ValueNotifier を使用します。 provider: ^6.0.5 を使用する必要はありませんが、どのような場合でも ValueNotifier を使用する方が便利です。これはあなたが に求めたものであり、その場合は新しいコピーを最初から作成する必要があるということです。
実際、ValueNotifier も非常に便利で、その後に <int> パラメータを指定して値の型を指定したり、この記事に基づいて監視データ型をカスタマイズしたりすることもできます。
- データモニターを定義する
ValueNotifier<String> activeSongValue = ValueNotifier<String>("1");
理論的には、これを任意のファイルに配置できますが、管理を容易にするために、ここでは曲の id を渡し、デフォルト値でフィルタリングすることをお勧めします。が "1" の場合、曲情報を取得するためにインターフェイスを呼び出さなくなりました (flutter 2.12 以降の Null 安全性の必須要件。最初は慣れませんでしたが、今ではかなり良いと思います)
- データの値を変更する
activeSongValue.value = _tem["id"];
直接使用するだけです。「provider」よりも簡単だと思われます。
- データの変化を監視する
ValueListenableBuilder コンストラクトを使用してリスニング部分を構築します
1return ValueListenableBuilder<String>(
2 valueListenable: activeSongValue, //监控器
3 builder: ((context, value, child) {
4 if (value != "1") { //改变值
5 _setAudioSource(value); //直接使用id进行查询等后续工作
6 }
7
8 return Container()...
- 曲情報を取得する
曲の id を取得したら、getSong を使用して音楽情報を取得し、getCoverArt を使用してアルバム画像を取得し、stream を使用してストリーム ファイルを取得します。
- 音楽ストリームを再生する
just_audio: ^0.9.31 を使用すると、開発の進行を大幅にスピードアップできます。これは 2 番目にランク付けされた依存関係ですが、たまたま、ここ数日のバージョンでは、公式文書のアドレスが失われています、これは運命と呼ばれます。
使い方も非常にシンプルで、ボタンスライダーなどのコントロールの表示に関わらず、音楽をクリックしてから再生を開始するまでのコードはたったの3行です。
1//定义组件
2final _player = AudioPlayer();
3//拼接流的url
4String _url = await getSongStreamUrl(_id);
5//获取流并播放
6 try {
7 await _player.setAudioSource(AudioSource.uri(Uri.parse(_url)));
8 _player.play();
9 } catch (e) {
10 print("Error loading audio source: $e");
11 }
上記は、デスクトップでのサーバーテスト、曲レベルのディレクトリへの入力、音楽の再生を含む現在の進行状況です。
まだまだ作業はたくさんありますが、バージョン 1 から注目しているのは Flutter です。モバイル端末への適応に注意するだけです。すべてを記述した後は、モバイルを調整するだけで十分だと思います。現在は単なる機能です)。
こちらは Github に来て遊んでみるのは良いことですが、これは開発専用であり、通常の使用とは程遠いものです。
