ポッドキャストから音声データを取得して再生できるアプリをFlutterで試みる。

`AndroidStudio`から入って`Create New Flutter Project`を選択し、エディタ(vsCode)で開きます。`main.dart`を開いたら`Run and Debug`を押します。
![スクリーンショット 2021-07-31 12.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/9442c5cf-07b6-0441-6586-19573e2dbd5a.png)
![スクリーンショット 2021-07-31 12.21.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/107e127d-f77c-e549-4176-29e1fa5860e8.png)
![スクリーンショット 2021-07-31 12.33.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/42d03933-a0eb-9d39-1e1d-6c9ad3b53099.png)
`ios`を選択して`Flutter Demo Home Page`が出てきたら準備完了です。
![スクリーンショット 2021-07-31 12.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/62db7145-3f75-5b22-bff5-f9675f6a6ca5.png)
`Text`を取り除いて、試しに再生アイコンを作ってみます。
![スクリーンショット 2021-07-31 14.05.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/934db283-746a-4a40-26be-bc380911f241.png)

```dart
Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  IconButton(
                    iconSize: 45.0,
                    color: Colors.black,
                    onPressed: () {},
                    icon: Icon(
                      Icons.skip_previous,
                    ),
                  ),
                  IconButton(
                    iconSize: 62.0,
                    color: Colors.black,
                    onPressed: () {},
                    icon: Icon(
                      Icons.play_arrow,
                    ),
                  ),
                    IconButton(
                    iconSize: 45.0,
                    color: Colors.black,
                    onPressed: () {},
                    icon: Icon(
                      Icons.skip_next,
                    ),
                  ),
                ],
            ),
```

実行してみると！？

![スクリーンショット 2021-07-31 14.13.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/b4f86332-57d0-d758-2c30-3330de05fbf3.png)
やる気出てきました！
次に、ポッドキャストの`iTunesUPodcast`の`RSS/XML`フィードを取得してみます。`pubspec.yaml`に`http: ^0.13.3`と`xml* ^5.1.2`を加えて、`main.dart`に以下を記述します。
![スクリーンショット 2021-07-31 16.08.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/01ca4f12-5062-940d-2e26-2321a264cb20.png)

```dart
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart';





@override
  void initState() {
    // アプリを起動時に一度だけ実行
    super.initState();
    
    Future(() async{
      var url = Uri.parse('http://www.nhk.or.jp/rj/podcast/rss/english.xml');
      print(await http.read(url));
      var response = await http.read(url);
      var document = XmlDocument.parse(response);
      final enclosures = document.findAllElements('enclosure');
      print(enclosures);
      enclosures.first.getAttribute("url");
      print(enclosures.first.getAttribute("url"));
    });
  }
```
実行して`DEBUG CONSOLE`を見てみると！それらしき物が取得できています！
![スクリーンショット 2021-07-31 16.19.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/fd989535-888e-c79d-0977-051d5d4e06fa.png)




`pubspec.yaml`に`video_player`パッケージの`Version 2.0.2`を入れます。
![スクリーンショット 2021-08-09 17.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/6dfdfd64-84f7-0604-c8e6-1e3def4f7ec1.png)

ルート直下に、`assets`ディレクトリを作りイメージ画像をドラッグ&ドロップで入れます。これは後に使用する為の画像です！
![スクリーンショット 2021-08-09 17.37.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/29127399-4b35-9e7a-3cef-21f58d36badf.png)

`pubspec.yaml`の`flutter:`内、`uses-material-design: true`の下に`assets: - assets/`を書きます。![スクリーンショット 2021-08-09 17.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/a3db1f9d-75ff-510f-1a7a-499116e13de6.png)

`lib`ディレクトリの`main.dart`を書き替えてとりあえず再生出来るようにうして行きます。

```dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart';
import 'package:video_player/video_player.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late VideoPlayerController _controller;
  @override
  void initState() {
    // アプリを起動時に一度だけ実行
    super.initState();

    Future(() async {
      var url = Uri.parse('http://www.nhk.or.jp/rj/podcast/rss/english.xml');
      // print(await http.read(url));
      var response = await http.read(url);
      var document = XmlDocument.parse(response);
      final enclosures = document.findAllElements('enclosure');
      // print(enclosures);
      enclosures.first.getAttribute("url");
      print(enclosures.first.getAttribute("url"));
      _controller = VideoPlayerController.network(
          (enclosures.first.getAttribute("url")).toString());
      _controller.initialize().then((_) {
        setState(() {});
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            padding: EdgeInsets.all(16),
            child: Icon(Icons.music_video, size: 256),
          ),
          VideoProgressIndicator(
            _controller,
            allowScrubbing: true,
          ),
          _ProgressText(controller: _controller),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              IconButton(
                onPressed: () {
                  _controller
                      .seekTo(Duration.zero)
                      .then((_) => _controller.play());
                },
                icon: Icon(Icons.refresh),
              ),
              IconButton(
                onPressed: () {
                  _controller.play();
                },
                icon: Icon(Icons.play_arrow),
              ),
              IconButton(
                onPressed: () {
                  _controller.pause();
                },
                icon: Icon(Icons.pause),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class _ProgressText extends StatefulWidget {
  final VideoPlayerController controller;

  const _ProgressText({
    Key? key,
    required this.controller,
  }) : super(key: key);

  @override
  __ProgressTextState createState() => __ProgressTextState();
}

class __ProgressTextState extends State<_ProgressText> {
  late VoidCallback _listener;

  __ProgressTextState() {
    _listener = () {
      setState(() {});
    };
  }

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(_listener);
  }

  @override
  void deactivate() {
    widget.controller.removeListener(_listener);
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    final String position = widget.controller.value.position.toString();
    final String duration = widget.controller.value.duration.toString();
    return Text('$position / $duration');
  }
}
```
それらしいのが作成出来ました。参照にさせて頂いたURL貼らせて頂きます。
[Fultterで始めるアプリ開発「音楽・動画を再生する」](https://www.flutter-study.dev/create-app/media-player/)


![スクリーンショット 2021-08-09 8.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/95613785-d4a5-a785-d862-781c99345fa0.png)

しっかりと再生出来ました!
ただ、これだと思っていたものと違うので装飾していきます。

```dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:xml/xml.dart';
import 'package:video_player/video_player.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
//アプリケーションのルートウィジェット  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
//こちらをfalseにすることでデバッグを消せます
      debugShowCheckedModeBanner: false,
      home: MyHomePage(title: ''),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late VideoPlayerController _controller;
//最初は再生させない
　bool playing = false;
//再生ボタンアイコン
  IconData playBtn = Icons.play_arrow;
//オブジェクトの宣言
  Duration position = new Duration();
  Duration musicLength = new Duration();
//プレーヤーの初期化
  @override
  void initState() {
// アプリを起動時に一度だけ実行
    super.initState();

    Future(() async {
      var url = Uri.parse('http://www.nhk.or.jp/rj/podcast/rss/english.xml');
      // print(await http.read(url));
      var response = await http.read(url);
      var document = XmlDocument.parse(response);
      final enclosures = document.findAllElements('enclosure');
      // print(enclosures);
      enclosures.first.getAttribute("url");
      print(enclosures.first.getAttribute("url"));
      _controller = VideoPlayerController.network(
          (enclosures.first.getAttribute("url")).toString());
      _controller.initialize().then((_) {
        setState(() {});
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
//メイン画面
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            width: double.infinity,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: [
                    Colors.green.shade800,
                    Colors.green.shade200,
                  ]),
            ),
            child: Padding(
                padding: EdgeInsets.only(
                  top: 48.0,
                ),
                child: Container(
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                      Padding(
                        padding: const EdgeInsets.only(left: 12.0),
                        child: Text(
                          "NHK WORLD RADIO JAPAN",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 38.0,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 12.0),
                        child: Text(
                          "This is the latest news in English from NHK WORLD RADIO JAPAN.",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 24.0,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                      ),
                      SizedBox(
                        height: 24.0,
                      ),
//こちらでアセッツに入れた画像を使います
                      Center(
                        child:Container(
                          width: 280.0,
                          height: 280.0,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(30.0),
                            image: DecorationImage(
                              image: AssetImage("assets/image.jpg"),
                            )),
                        ),
                      ),
                      SizedBox(
                        height: 18.0,
                      ),
                      Center(
                        child: Text(
                          "English News",
                          style: TextStyle(
                            color: Colors.white,
                            fontSize: 32.0,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                      ),
                      SizedBox(
                        height: 30.0,
                      ),
                      Expanded(
                          child: Container(
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(30.0),
                            topRight: Radius.circular(30.0),
                          ),
                        ),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
//プログレスバーを表示
                            VideoProgressIndicator(
                              _controller,
                              allowScrubbing: true,
                            ),
                            _ProgressText(controller: _controller),
                            Row(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                              children: [
                                IconButton(
                                  iconSize: 62.0,
                                  color: Colors.blue,
                                  onPressed: () {
//再生ボタンの機能追加、停止の場合は音を止める
                                    if (!playing) {
                                      _controller.play();
                                      setState(() {
                                        playBtn = Icons.pause;
                                        playing = true;
                                      });
                                    } else {
                                      _controller.pause();
                                      setState(() {
                                        playBtn = Icons.play_arrow;
                                        playing = false;
                                      });
                                    }
                                  },
                                  icon: Icon(
                                    playBtn,
                                  ),
                                ),
//リロード
                                IconButton(
                                  iconSize: 62.0,
                                  color: Colors.red,
                                  onPressed: () {
                                    _controller
                                        .seekTo(Duration.zero)
                                        .then((_) => _controller.pause());
                                  },
                                  icon: Icon(Icons.refresh),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ))
                    ]
                  )
                )
              )
            )
          );
  }
}
//現在の再生時間を表示する
class _ProgressText extends StatefulWidget {
  final VideoPlayerController controller;

  const _ProgressText({
    Key? key,
    required this.controller,
  }) : super(key: key);

  @override
  __ProgressTextState createState() => __ProgressTextState();
}

class __ProgressTextState extends State<_ProgressText> {
  late VoidCallback _listener;

  __ProgressTextState() {
    _listener = () {
      setState(() {});
    };
  }

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(_listener);
  }

  @override
  void deactivate() {
    widget.controller.removeListener(_listener);
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    final String position = widget.controller.value.position.toString();
    final String duration = widget.controller.value.duration.toString();
    return Text('$position / $duration');
  }
}
```
実行してみましょう。




![スクリーンショット 2021-08-09 16.19.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/c2272ac1-6678-a679-f41d-4f7d147c7559.png)
良い感じに仕上がりました。次回は実機を取り入れアプリを開発してみようと思います。