Flutter で Nas 音楽プレーヤーを作成する (1)
2023-01-05 22:40 ≈ 982字 ≈ 4分

ここ 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 でも試すことができます。

検証サーバー

1672924014867

一見するとわかりにくいように思えるかもしれませんが、実際には非常に単純な 2 種類の検証があります。パスワード を渡すか、暗号化された (パスワード + 6 Salt値) に 6 Salt値 を加えたものを渡します

まず、テストするサーバーにPingを実行します (dio: ^4.0.6 を使用すると、多くの操作を節約できます)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
try {
var response = await Dio().get(
_baseUrl +
'rest/ping?v=0.0.1&c=xiumusic&f=json&u=' +
_username + //v はクライアントのバージョン番号、c はクライアントの名前、u はユーザー名、p はパスワードです
'&p=' +
_password,
);
print(response);
if (response.statusCode == 200) {
//ここでもう 1 つのステップを実行する必要があります。つまり、code200 が返されても満足せず、subsonicサーバーからのフィードバックを確認します。
Map _value = response.data['subsonic-response'];
String _status = _value['status'];
//通常は問題ありません、私は自給自足です、自己デバッグ中です、アップグレードするときはこの状況を認める必要があります、わかりません、わかりません。
if (_status == 'failed') {
return false;
} else {
return true;
}
} else {
return false;
}
} catch (e) {
print(e);
return false;
}

2 段階認証サーバーと Subsonic の API が完了したら、後続のすべての API でその値を取得するために Salt を使用できます。これらはすべて無料です。

暗号化されたログイン

  1. Rondom を使用して、ランダムに生成された 6 桁の文字を書き込みます
1
2
3
4
5
6
7
8
9
10
String generateRandomString() {
final _random = Random();
const _availableChars =
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
final randomString = List.generate(6,
(index) => _availableChars[_random.nextInt(_availableChars.length)])
.join();

return randomString;
}
  1. スプライシング後に MD5 暗号化を使用します。

後で API で使用するためにこれらの 2 文字を保存します。

ディレクトリの取得

Subsonic のディレクトリは上から下にこのように分類されます

  • 音楽フォルダー
  • アーティストフォルダー
  • アルバム

ただし、Navidrome には音楽フォルダーが 1 つしかないようなので、第 2 レベルの getIndexes を直接使用してディレクトリ マスター リストを作成し、その後 ミュージシャン ID に基づいてアルバム リストに進みました。

1672925500580

音楽を再生

変更量を変更するには ValueNotifier を使用します。 provider: ^6.0.5 を使用する必要はありませんが、どのような場合でも ValueNotifier を使用する方が便利です。これはあなたが に求めたものであり、その場合は新しいコピーを最初から作成する必要があるということです。

実際、ValueNotifier も非常に便利で、その後に <int> パラメータを指定して値の型を指定したり、この記事に基づいて監視データ型をカスタマイズしたりすることもできます。

  1. データモニターを定義する

ValueNotifier<String> activeSongValue = ValueNotifier<String>("1");

理論的には、これを任意のファイルに配置できますが、管理を容易にするために、ここでは曲の id を渡し、デフォルト値でフィルタリングすることをお勧めします。が "1" の場合、曲情報を取得するためにインターフェイスを呼び出さなくなりました (flutter 2.12 以降の Null 安全性の必須要件。最初は慣れませんでしたが、今ではかなり良いと思います)

  1. データの値を変更する

activeSongValue.value = _tem["id"];

直接使用するだけです。「provider」よりも簡単だと思われます。

  1. データの変化を監視する

ValueListenableBuilder コンストラクトを使用してリスニング部分を構築します

1
2
3
4
5
6
7
8
return ValueListenableBuilder<String>(
valueListenable: activeSongValue, //监控器
builder: ((context, value, child) {
if (value != "1") { //改变值
_setAudioSource(value); //直接使用id进行查询等后续工作
}

return Container()...
  1. 曲情報を取得する

曲の id を取得したら、getSong を使用して音楽情報を取得し、getCoverArt を使用してアルバム画像を取得し、stream を使用してストリーム ファイルを取得します。

  1. 音楽ストリームを再生する

just_audio: ^0.9.31 を使用すると、開発の進行を大幅にスピードアップできます。これは 2 番目にランク付けされた依存関係ですが、たまたま、ここ数日のバージョンでは、公式文書のアドレスが失われています、これは運命と呼ばれます。

使い方も非常にシンプルで、ボタンスライダーなどのコントロールの表示に関わらず、音楽をクリックしてから再生を開始するまでのコードはたったの3行です。

1
2
3
4
5
6
7
8
9
10
11
//定义组件
final _player = AudioPlayer();
//拼接流的url
String _url = await getSongStreamUrl(_id);
//获取流并播放
try {
await _player.setAudioSource(AudioSource.uri(Uri.parse(_url)));
_player.play();
} catch (e) {
print("Error loading audio source: $e");
}

上記は、デスクトップでのサーバーテスト、曲レベルのディレクトリへの入力、音楽の再生を含む現在の進行状況です。

まだまだ作業はたくさんありますが、バージョン 1 から注目しているのは Flutter です。モバイル端末への適応に注意するだけです。すべてを記述した後は、モバイルを調整するだけで十分だと思います。現在は単なる機能です)。

こちらは Github に来て遊んでみるのは良いことですが、これは開発専用であり、通常の使用とは程遠いものです。