[Flutter] Youtube Data API で動画情報を取得

概要

Flutter から Youtube Data API を呼び出しで、動画情報を画面表示する。

環境

  • Flutter 2.10.3
  • iPhone SE (2nd generation) シミュレータ
  • http: ^0.13.4

設計

Youtube Data API を curl で叩く

例えば、この Youtube 動画情報を取得する場合。

curl "https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY&part=snippet,contentDetails"

呼び出し API を簡単に解説。

  • https://www.googleapis.com : Google の API 群の URL
  • youtube/v3/video : Youtube の動画情報を指定
  • YOUR_API_KEY : 自分の API アクセスキー
  • part : リソースに対して返すプロパティグループを指定、今回は snippet と contentDetails
    • ex) video の場合は以下
    • snippet
    • contentDetails
    • fileDetails
    • player
    • processingDetails
    • recordingDetails
    • statistics
    • status
    • suggestions
    • topicDetails

レスポンスは JSON 形式で返ってくる。

{
  "kind": "youtube#videoListResponse",
  "etag": "8hPPwge2QCmXWScALfQ-1Wpdt-I",
  "items": [
    {
      "kind": "youtube#video",
      "etag": "AyPr64fEkkob-G5vdgO83EFAj-U",
      "id": "7lCDEYXw3mM",
      "snippet": {
        "publishedAt": "2012-06-20T23:12:38Z",
        "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
        "title": "Google I/O 101: Q&A On Using Google APIs",
        "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "Google Developers",
        "tags": [
          "api",
          "gdl",
          "i-o"
        ],
        "categoryId": "28",
        "liveBroadcastContent": "none",
        "localized": {
          "title": "Google I/O 101: Q&A On Using Google APIs",
          "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0."
        }
      },
      "contentDetails": {
        "duration": "PT15M51S",
        "dimension": "2d",
        "definition": "hd",
        "caption": "true",
        "licensedContent": false,
        "contentRating": {},
        "projection": "rectangular"
      }
    }
  ],
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  }
}

取得するデータによって、クォータの使用量に制限がかかることがあるため注意。

モデル設計

レスポンス情報を保持するモデルクラスを定義する。

今回は簡単に title と description 情報だけを取り扱う。

class Video {
  final String title;
  final String description;

  const Album({
    required this.title,
    required this.description,
    
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}

チュートリアル

Youtube API 有効化・API アクセスキー取得

下記参照。

Flutter プロジェクト作成

Flutter プロジェクト作成。

flutter create test_youtube_api
cd test_youtube_api

ライブラリ追加。

flutter pub add http

コードを MVVM で分けた

main.dart

import 'package:flutter/material.dart';

import 'view.dart';

void main() => runApp(const MyApp());

view.dart

import 'package:flutter/material.dart';

import 'view_model.dart';
import 'model.dart';

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  late Future<Album> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Youtube Data API Example'),
        ),
        body: Center(
          child: FutureBuilder<Album>(
            future: futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Column(
                  children: const <Widget>[
                    Text(snapshot.data!.title),
                    Text(snapshot.data!.description),
                  ]
                );
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }

              // By default, show a loading spinner.
              return const CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

view_model.dart

import 'dart:async';
import 'dart:convert';

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

import 'model.dart';

Future<Album> fetchAlbum() async {
  final id = "7lCDEYXw3mM";
  final key = "自分のキー";
  final part = "snippet";
  //final part = "snippet,contentDetails,statistics,status"
  
  final url = Uri.parse('https://www.googleapis.com/youtube/v3/videos?id=${id}&key=${key}&part=${part}');
  final response = await http.get(url);

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

model.dart

class Album {
  final String title;
  final String description;
  

  const Album({
    required this.title,
    required this.description,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      title: json['items'][0]['snippet']['title'],
      description: json['items'][0]['snippet']['description'],
    );
  }
}

起動確認

起動。

flutter run

起動し、以下のように title と description を取得・表示できればOK。
(画面汚いw)

参考

YouTube Data API の概要  |  Google for Developers

コメント

タイトルとURLをコピーしました