Flutter で Nas 音楽プレーヤーを作成する (1)

2023-01-05 22:40≈ 356字≈ 2分

ここ 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  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 を使用できます。これらはすべて無料です。

暗号化されたログイン

  1. 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}
  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 コンストラクトを使用してリスニング部分を構築します

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

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

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

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 に来て遊んでみるのは良いことですが、これは開発専用であり、通常の使用とは程遠いものです。