Displaying Popular Youtube Videos in Flutter App with Youtube API

Displaying Popular Youtube Videos in Flutter App with Youtube API

Hello everyone, welcome back again at porkaone. On this occasion we will learn how to display popular YouTube videos with the YouTube API in the Flutter application. Are you curious? Come on, follow the details below.


Previously I made a tutorial on how to display YouTube videos with YouTube API in Flutter. Here is the link to the article https://www.porkaone.com/2023/12/how-to-display-youtube-videos-from.html

The difference with this tutorial is that we will show popular YouTube videos but still use the YouTube API. Apart from that, we will also display the total likes and total views. So we will also modify the model and appearance. Scroll to the bottom of this article to see the final results.


Read Another Article ✨
📰 1. How to Create a Select Dropdown with API in Flutter  read more
📰 2. How to Create a Select Input Dropdown in Flutter  read more
📰 3. How to Make a QR Code Scanner in Flutter ENV read more
📰 4. How to Display Youtube Videos in Flutter  read more


Displaying Popular Youtube Videos in Flutter App with Youtube API

1. First and foremost, you must have a YouTube API key first. If you don't have it, please follow the following tutorial https://www.porkaone.com/2023/12/how-to-get-youtube-api-key.html

2. Create a new file with the name you want. The flutter used is the null safety version. sdk: ">=2.16.2 <3.0.0". A slightly lower or slightly higher version difference doesn't matter.

3. Open pubspec.yaml. Then add http: ^0.13.5 and youtube_player_flutter: ^8.0.0, follow the example as shown below.

Add Package



4. Create a new file in the lib folder with the name video_model.dart then follow the script below.



class Video { final String id; final String title; final String thumbnail; final String channelTitle; final int viewCount; final int likeCount; Video({ required this.id, required this.title, required this.thumbnail, required this.channelTitle, required this.viewCount, required this.likeCount, }); factory Video.fromJson(Map<String, dynamic> json) { return Video( id: json['id'] ?? '', title: json['snippet']['title'] ?? '', thumbnail: json['snippet']['thumbnails']['high']['url'] ?? '', channelTitle: json['snippet']['channelTitle'] ?? '', viewCount: int.tryParse(json['statistics']['viewCount']) ?? 0, likeCount: int.tryParse(json['statistics']['likeCount']) ?? 0, ); } }


5. Create a new file in the lib folder with the name youtube_api.dart then follow the script below. Don't forget to replace key=YOUR_KEY with the YouTube API key that you have.



import 'dart:convert'; import 'package:http/http.dart' as http; import 'video_model.dart'; class YouTubeApi { Future<List<Video>> getVideos() async { final url = 'https://www.googleapis.com/youtube/v3/videos' '?part=snippet' '&part=statistics' '&chart=mostPopular' '&maxResults=10' '&type=video' '&key=YOUR_KEY'; final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { final jsonData = json.decode(response.body); final videoList = jsonData['items'] as List<dynamic>; return videoList.map((item) => Video.fromJson(item)).toList(); } else { throw Exception('Failed to load videos'); } } }


5. Create a new file in the lib folder with the name detail.dart then follow the script below.

 

import 'package:flutter/material.dart'; import 'package:youtube_player_flutter/youtube_player_flutter.dart'; import 'video_model.dart'; import 'youtube_api.dart'; class Detail extends StatefulWidget { final String videoId; final String title; Detail({ required this.videoId, required this.title, }); @override State<Detail> createState() => _DetailState(); } class _DetailState extends State<Detail> { late YoutubePlayerController _controller; @override void initState() { super.initState(); _controller = YoutubePlayerController( initialVideoId: YoutubePlayer.convertUrlToId( 'https://www.youtube.com/watch?v=' + widget.videoId)!, flags: const YoutubePlayerFlags( autoPlay: false, mute: false, ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Video Detail'), ), body: ListView( children: [ YoutubePlayer( controller: _controller, showVideoProgressIndicator: true, progressIndicatorColor: Colors.blueAccent, ), Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 35, height: 35, decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(20)), image: DecorationImage( fit: BoxFit.cover, image: NetworkImage( 'https://cdn.pixabay.com/photo/2016/11/18/23/38/child-1837375_640.png', ), ), ), ), const SizedBox( width: 10, ), Expanded( child: Text( widget.title, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w400), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ], ), const SizedBox( height: 20, ), const Text( 'See Other Videos', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500), ), const SizedBox( height: 15, ), FutureBuilder<List<Video>>( future: YouTubeApi().getVideos(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( child: CircularProgressIndicator(), ); } else if (snapshot.hasData) { final videos = snapshot.data!; return ListView.builder( padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: videos.length, itemBuilder: (context, index) { final video = videos[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ InkWell( onTap: () => { Navigator.push( context, MaterialPageRoute( builder: (context) => Detail( videoId: video.id, title: video.title, ), ), ) }, child: ListTile( contentPadding: EdgeInsets.zero, leading: Image.network( video.thumbnail, fit: BoxFit.cover, width: 120, ), title: Text( video.title, maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ), const SizedBox( height: 8, ), ], ); }, ); } else if (snapshot.hasError) { return Center( child: Text('Error: ${snapshot.error}'), ); } else { return Center( child: Text('Failed to load videos'), ); } }, ), ], ), ) ], ), ); } }



6. Open lib/main.dart then follow the script below.



import 'package:flutter/material.dart'; import 'detail.dart'; import 'video_model.dart'; import 'youtube_api.dart'; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { String formatNumber(dynamic number) { if (number >= 1000000) { return (number ~/ 1000000).toString() + ' jt'; } else if (number >= 1000) { return (number ~/ 1000).toString() + ' rb'; } else { return number.toString(); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('YouTube Videos'), ), body: FutureBuilder<List<Video>>( future: YouTubeApi().getVideos(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( child: CircularProgressIndicator(), ); } else if (snapshot.hasData) { final videos = snapshot.data!; return ListView.builder( itemCount: videos.length, itemBuilder: (context, index) { final video = videos[index]; return InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Detail( videoId: video.id, title: video.title, ), ), ); }, child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.network( video.thumbnail, width: double.infinity, height: 160, fit: BoxFit.cover, ), const SizedBox( height: 5, ), Padding( padding: EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 45, height: 45, decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(20)), image: DecorationImage( fit: BoxFit.cover, image: NetworkImage( 'https://cdn.pixabay.com/photo/2016/11/18/23/38/child-1837375_640.png', ), ), ), ), const SizedBox( width: 10, ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( video.title, style: const TextStyle( fontSize: 16, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), SizedBox( height: 5, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( video.channelTitle, style: const TextStyle( fontSize: 12, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), Row( children: [ Icon( Icons.thumb_up, size: 14, ), SizedBox(width: 5), Text( formatNumber(video.likeCount), style: const TextStyle( fontSize: 12, ), ), SizedBox(width: 10), Icon( Icons.remove_red_eye, size: 14, ), SizedBox(width: 5), Text( formatNumber(video.viewCount), style: const TextStyle( fontSize: 12, ), ), SizedBox(width: 16,) ], ) ], ), ], ), ), ], ), ), SizedBox( height: 10, ) ], ), ), ); }, ); } else if (snapshot.hasError) { return Center( child: Text('Error: ${snapshot.error}'), ); } else { return Center( child: Text('Failed to load videos'), ); } }, ), ), ); } }


If we have done all the steps, it's time to do a trial. Please run the emulator, if successful then the display will look like the image below.

sahretechsahretech



It's easy, isn't it?, now you can display data from YouTube and process it into the various application needs that you have. You can improvise by adding searches or displaying videos in certain categories.

OK, that's it for this tutorial on how to display popular YouTube videos in the Flutter application with YouTube Api. Hopefully this short tutorial is useful, if there are problems, please report them directly in the comments column below. That's all and receive a salary.


Post a Comment

0 Comments