Flutter Live Streaming App Report
Flutter Live Streaming App Report
On
LIVE STREAMING APPLICATION USING FLUTTER
(PLAYSAR)
Submitted in partial fulfillment of the requirement for the award of the degree of
BACHELOR OF TECHNOLOGY
IN
COMPUTER SCIENCE ENGINEERING
By:
MOHD HASHIM (100190133)
i
Sir Chhotu Ram Institute Of Engg. & Tech.
Approved by A.I.C.T.E., New Delhi
CERTIFICATE-I
This is to certify that this project report entitled “LIVE STREAMING APPLICATION
USING FLUTTER” which is submitted by Mohd Hashim(100190133), Madhavi
Singh(100190129), Mohd Farman(100190132), in the partial fulfillment of the requirement for
the award of degree of Bachelor of Technology in Computer Science Engineering from this
college is a record of candidate own work carried out by him/her under our supervision.
The matter embodied in this Project Report has not been submitted earlier for award of any degree
or diploma in any university/institution to the best of our knowledge & belief.
(……..…………..) (..………………….)
(Project Guide) (Project Co-ordinator)
Date: //
ii
Sir Chhotu Ram Institute Of Engg. & Tech.
Approved by A.I.C.T.E., New Delhi
CERTIFICATE-II
(……………….) (………..……….)
Internal Examiner External Examiner
(………………….)
(Co-ordinator)
Department of (CSE)
(…….………………)
Director, SCRIET
iii
ACKNOWLEDGEMENT
It gives me a great sense of pleasure to present the report of the Project Work undertaken
during B. Tech. Final Year. I owe special debt of gratitude to my Project Coordinator Er. Ritu
Sharma, Department of Computer Science Engineering, SCRIET C.C.S. University, Meerut for
her/his constant support and guidance throughout the course of my work. It is only her/his
cognizant efforts that my endeavors have seen light of the day.
My deepest thanks to my Project Guide Er. Milind Co-ordinator ,CSE, SCRIET, CCS University
Meerut, forguiding throughout the project.
I also take the opportunity to acknowledge the contribution of Prof. Neeraj Singhal, Director,
SCRIET CCS University, Meerut and Er.Milind, Assistant Professor & Coordinator
Department of Computer Science Engineering, SCRIET, Meerut for his full support and
assistance during the development of the project.
I also do not like to miss the opportunity to acknowledge the contribution of all faculty members
of the department for their kind assistance and cooperation during the development ofmy project.
Last but not the least, I acknowledge my friends for their contribution in the completion of the
project.
iv
INDEX
Front page i
Declaration ii
Certification iii
Acknowledgement iv
Table of contents 1
Abstract 3
CHAPTER
1. INTRODUCTION……………………………………………. 4-5
1.1 Objectives 4
1.2 Overview 4
1.3 Proposed System 5
2. SYSTEM ANALYSIS…………………………………………...6-9
2.1 Objective 6
2.2 SDLC Phases 6-7
2.3 Class Diagram 8
2.4 Architecture of Playsar 9
3. TECHNOLOGY…………………………………………..10-11
3.1 Introduction of Flutter 10
3.1.1 Features
3.2 Node Js server 11
3.2.1 feature 0f js
3.3 Software requirement Specification 12
3.3.1 Functional Requirement
3.3.2 Hardware Requirement
3.3.3 Software Requirement
4. CODING…………………………………………………13-82
4.1 Backend Coding 13
4.1.1 package Jason
4.1.2 Routers
4.2 Backend Coding 29
4.2.1 Widgets
4.3 Data 60
4.4 Domain 73
1
4.5 Bloc 75
5. DIRECTORY STRUCTURE………………………………83-85
5.1 D structure 83
5.2 Front End directory Structure 84
5.3 Back End Directory Structure 85
6. TESTING AND SCREENSHOTS ……………………….86-96
6.1 Testing 86
6.2 Types of Testing 86
6.3 Screenshots 87
7. CONCLUSION ………………………………………………..97
8. REFERENCE………………………………………………….98
2
ABSTRACT
We are developing a “Playsar” by taking advantages of the flutter platform. The main concept of
this project is to build a Mobile Application, which should be able to allow people to give entertain
-ment and show all some live Indian news channel.
Time saving working load reduce. This app including the features of trending entertainment
movies, web- series, live news channels and comedies .
This is a simple, safe and secure method that takes minimum of time. We are to maintaining a
server by using node JS also express JS for routing.
Live streaming services whereby video is broadcast in real time, have been adopted by many
small individual sellers as a direct selling tool. Drawing on literature in retailing, adoption behavior,
and electronic commerce, this paper proposes a comprehensive framework with which to examine
the relationships among customers' perceived value of live streaming, customer trust, and
engagement. Symbolic value is found to have a direct and indirect effect via trust in sellers on
customer engagement, while utilitarian and hedonic values are shown to affect customer
engagement indirectly through customer trust in products and trust in sellers sequentially.
Elucidating the role of live streaming in increasing sales and loyalty, these findings suggest different
routes through which small online sellers can build customer engagement with two types of trust
as mediators. Theoretical and managerial implications of this analysis for social commerce are
further discussed at the conclusion of this paper.
3
CHAPTER 1
INTRODUCTION
“PLAYSAR” is an Live Video Streaming app. In which user can view the trending movies,
web-series and live tele channel. There is a NodeJS using for back-end server management and
Flutter using for front-end app development.
1.1 Objective
To develop live video streaming app.
To implement live news broadcast ...
To develop custom video streaming app.
To establish the connection b/w user and server provider.
To provide the better quality of video streaming.
To provide video streaming in better quality, audio filter, video orientation, subtitle and
playback speed management
1.2 Overview
Video streaming has received much attention for some time now, and its popularity has grown
manifold in the last decade, particularly with the deployment of widely known video streaming
services, such as YouTube, Netflix, Hulu, Daily Motion, and others. Video streaming now accounts
for a large share of the total traffic the Internet, and as such the transmission mechanisms used by
video servers have an impact not only on the quality of the video presentation to the clients, but also
on the total traffic impact on the network. Video streaming, in various forms of video on demand
(VOD), live, and 360 degree streaming, has grown dramatically during the past few years. In
comparison to traditional cable broadcasters whose contents can only be watched on TVs, video
streaming is ubiquitous and viewers can flexibly watch the video contents on various devices,
ranging from smartphones to laptops, and large TV screens. Such ubiquity and flexibility are enabled
by interweaving multiple technologies, such as video compression, cloud computing, content
delivery networks, and several other technologies. As video streaming gains more popularity and
dominates the Internet traffic, it is essential to understand the way it operates and the interplay of
different technologies involved in it. Accordingly, the first goal of this paper is to unveil
sophisticated processes to deliver a raw captured video to viewers’ devices. In particular, we
elaborate on the video encoding, transcoding, packaging, encryption, and delivery processes. We
survey recent efforts in academia and industry to enhance these processes. As video streaming
industry is increasingly becoming reliant on cloud computing, the second goal of this survey is to
explore and survey the ways cloud services are utilized to enable video streaming services. The third
goal of the study is to position the undertaken research works in cloud-based video streaming and
identify challenges that need to be obviated in future to advance cloud-based video streaming
industry to a more flexible and user-centric service.
4
1.3 Project modules of Live Streaming Application:
Accounts:In this module user can register by entering their profile information. After
registration user can access accounts page by entering login id and password.
Video manager: This module allows user to upload videos and they can edit uploaded
videodescription and its contents.
My Channel:In this module the visitors can add or subscribe users channel by entering
theirEmail ID. Whenever the user uploads new video it sends mail notification to the visitor.
Events broadcasting: This module can be used to broadcast a live events. The Live module
home page contains list of events and Completed Events sections.The user needs to enter event
name, event date, event time, etc.
Dashboard module: There are two types of users in this module. They are administrator
andemployees.
Live broadcasting: This module is for administrator where administrator can stream
TVchannels by entering embedded link.
Subscription: In this module user can subscribe for live broadcasting by making payment.
Afterconfirmation of the payment the user can watch and record videos. The subscribed member
can download the videos by clicking download button.
Comments and likes:The registered user can post their comments and like the uploaded videos.
5
CHAPTER 2
SYSTEM ANALYSIS
2.1 Objective
The specific objectives of the project include:
To develop live video streaming app.
To implement live news broadcast ...
To develop custom video streaming app.
To establish the connection b/w user and server provider.
To provide the better quality of video streaming.
To provide video streaming in better quality, audio filter, video orientation, subtitle and
play back speed management .
6
4. System Design
System design means the design of the system. The system can be done in either of the
following two ways:-
Logical System Design
Physical System Design
5. Coding
Coding is the phase in which a developer codes using any programming language. Coding
constitution only 20% of the whole project and which is easier to write. The coding work is also
done in the terms; development of the system is usually done under the modular programming style,
which can be either top-down approach or bottom-up approach.
6. Testing
Testing is the phase in which the system that has been developed is tested. Testing comprises
of the 60% of the overall development of the system. Testing of the system is important because
testing aims to uncover the different errors in the system. There are various different testing
techniques that can be used for the testing of the system.
7. Implementation
Implementation process involved the installation of software on user’s side. Implementation
process actually depends on types of a system & various. Opting for suitable conversion approach
is step implementation. The conversion process are as follows.
Bloc Pattern
8. Maintenance
Merely developing the system is not import but also maintenance is important. The company
that has built the system provides for some time free of cost maintenance to the client and after that
period it is usually a paid service.
7
2.3 Class Diagram
8
2.4 Architecture of playsar
PlaySAR
Play
series
Play
movie
Play
channel
Play music
9
CHAPTER 3
TECHNOLOGY USED
• Open-source Platform. Flutter is an open-source platform developed and backed by Google. ...
• Hot Reload. ...
• Rich Widgets. ...
• Single Code Base. ...
• Google Firebase Support. ...
• Rapid App Development. ...
• Single Codebase for Both Platforms. ...
• Expressive Interfaces.
Version of Flutter
10
3.2 NodeJS SERVER
• Asynchronous and Event Driven − All APIs of Node. js library are asynchronous, that is,
non-blocking. ...
• Very Fast − Being built on Google Chrome's V8 JavaScript Engine, Node. js library is
very fast in code execution.
• Single Threaded but Highly Scalable − Node. ...
• No Buffering − Node. ...
• License − Node.
11
CHAPTER 4
CODING
const token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJIcml0aWsiLCJuYW1lIjoiWW91d2lsbG5ldmVyZ2V0aXQiLCJpY
XQiOjE1MTYyMzkwMjJ9.6PRPWzmu_or76BASRLuP59ALvgWdQ8viGM9aThRojyY';
app.use(express.json());
app.use(cors());
//animeList
const animeList = require('./routers/anime_list');
app.use('/animeList',authorization ,animeList);
//home page
//Trending List
const trendingList = require('./routers/trending');
app.use('/trendingList',authorization ,trendingList);
//Trending List
const newArrivalsList = require('./routers/new_arrivals');
app.use('/newarrivals',authorization ,newArrivalsList);
//featuredbanner
const featuredBanner = require('./routers/featuredBanner');
app.use('/featuredBanner',authorization ,featuredBanner);
//comming_soon
const comming_soon = require('./routers/comming_soon');
app.use('/commingsoon',authorization,comming_soon);
//movie categories
//animationMovieCategory
const AnimatedMovies = require('./routers/Animated_movies');
app.use('/animatedMovies',authorization,AnimatedMovies);
//series
//animated series
const animatedSeries = require('./routers/animated_series');
app.use('/animatedSeries',authorization,animatedSeries);
//horror series
const horrorSeries = require('./routers/horror_series');
app.use('/horrorSeries',authorization,horrorSeries);
//action series
const actionSeries = require('./routers/action_series');
app.use('/actionSeries',authorization,actionSeries);
//starting route
app.get('/', authorization ,(req,res) => {
if(req.Auth){
res.send("Server Connected");
}else{
res.send('Auth fail');
}
});
//authorization
function authorization(req,res,next){
req.Auth = false;
}
if(reqtoken === token){
req.Auth = true;
}else{
req.Auth = false;
}
next();
}
13
console.log(`Server started on `+"192.168.1.9"+":"+PORT);
});
} catch (error) {
console.log(error);
}
}
startServer();
4.1.1 package.json
{
"name": "playsar",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon server.js"
},
"author": "Subhash Chandra Shukla",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1"
},
"devDependencies": {
"nodemon": "^2.0.7"
}
}
4.1.2 Routers
1. ActionMovie.js
const resJson_actionMoviesList = [
{
"name":"Godzilla vs Kong(Hindi audio)",
"logo":"https://images-na.ssl-images-amazon.com/images/I/81SAqNnNlfL._AC_SL1500_.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"Hindi",
"description":"Godzilla vs. Kong is a 2021 American monster film directed by Adam Wingard. A
sequel to Godzilla: King of the Monsters (2019) and Kong: Skull Island (2017), it is the fourth film
in Legendary's MonsterVerse. It is also the 36th film in the Godzilla franchise, the 12th film in the
King Kong franchise, and the fourth Godzilla film to be completely produced by a Hollywood studio.
The film stars Alexander Skarsgård, Millie Bobby Brown, Rebecca Hall, Brian Tyree Henry, Shun
Oguri, Eiza González, Julian Dennison, Lance Reddick, Kyle Chandler, and Demián Bichir. In the
film, Kong clashes with Godzilla as humans lure the ape into the Hollow Earth to retrieve a power
source for a weapon to stop Godzilla's mysterious rampages."
14
},
];
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
2. ActionSeries.js
const resJson_actionSeriesList = [
{
"name":"ekk",
"logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"description":"this is new series",
"seasons":[
{
"seasonName" : "season1",
"seasonDescription":"this is first season",
"seasonLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg", "episodes":[
{
"episodeName":"episode1",
"episodeDescription":"this is first episode" ,
"episodeUrl":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"episodeLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg"
}
]
}
],
"language":"English"
},
];
15
router.get('/', async (req,res) => {
if(req.Auth){
try { res.status('200').send(resJson_actionSeriesList);
} catch (error) {
res.status('500').send('Server error');
}
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
3. Animated Movies
const express = require('express');
const router = express.Router();
const resJson_animationMovieList = [
{
"name":"Panda Vs Aliens(720p)",
"logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"A group of aliens seek out to conquer new worlds and take particular notice of Earth, after seeing
satellite broadcasts of TV shows of a powerful panda, Pandy."
},
];
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
16
4. Animated Series
const resJson_animatedSeriesList = [
{
"name":"ekk", "logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"description":"this is new series",
"seasons":[
{
"seasonName" : "season1",
"seasonDescription":"this is first season",
"seasonLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"episodes":[
{
"episodeName":"episode1", "episodeDescription":"this
is first episode" ,
"episodeUrl":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseli
ne.m3u8",
"episodeLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg"
}
]
}
],
"language":"English"
},
];
}
else{
res.status('400').send('Auth fail');
}});
module.exports = router;
17
5. AnimList.js
const resJson_animeList = [
{
"name":"Rent a girlfriend",
"logo":"https://upload.wikimedia.org/wikipedia/pt/d/de/Kanojo%2C_Okarishimasu_poster.jpg",
"type":"m38u",
"url":"https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899- f0f6155f6efa.m3u8"
},
];
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
6. ComingSoon.js
const resJson_CommingSoon = [
{
},{
18
},{
},{
},
];
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
7. FeaturedBanner.js
const resJson_featuredBanner = {
};
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
8. horror_movie.js
const resJson_horrorMoviesList = [
{
"name":"Blue call(360p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
xODA2MTA@._V1_FMjpg_UY682_.jpg",
"type":"m38u", "url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},
{
"name":"Blue call(720p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
xODA2MTA@._V1_FMjpg_UY682_.jpg",
"type":"m38u", "url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},
];
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
9. horror_series.js
const express = require('express');
const router = express.Router();
const resJson_horrorSeriesList = [
{
"name":"ekk",
"logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"description":"this is new series",
"seasons":[
{
"seasonName" : "season1",
"seasonDescription":"this is first season",
"seasonLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg", "episodes":[
{
"episodeName":"episode1",
"episodeDescription":"this is first episode" ,
"episodeUrl":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"episodeLogo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg"
}
]
}
],
"language":"English"
},
];
21
} catch (error) {
res.status('500').send('Server error');
}
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
10. indian_channel_list.js
const express = require('express');
const router = express.Router();
const resJson_IndianChannelList = [
{
"name": "&Flix",
"logo": "https://static.epg.best/in/AndFlix.in.png", "type":"m38u",
"url": "https://y5w8j4a9.ssl.hwcdn.net/andflixhd/tracks-v1a1/index.m3u8",
"category": "Movies"
},
{
"name": "&privé HD",
"logo": "https://upload.wikimedia.org/wikipedia/en/4/4f/Logo_of_%26_Priv%C3%A9_HD.jpg",
"type":"m38u",
"url": "https://y5w8j4a9.ssl.hwcdn.net/andprivehd/tracks-v1a1/index.m3u8",
"category": "Movies"
},
{
"name": "3 Tamil TV",
"logo": "https://i.imgur.com/WfAU7pB.png",
"type":"m38u",
"url": "https://6n3yogbnd9ok-hls-
live.5centscdn.com/threetamil/d0dbe915091d400bd8ee7f27f0791303.sdp/index.m3u8",
"category": "Entertainment"
},
{
"name": "7X Music",
"logo": "https://i.imgur.com/fD7wLka.jpg", "type":"m38u",
"url": "http://newsjatt.camdvr.org:1935/newsjatt/myStream/playlist.m3u8", "category":
"Music"
},
{
"name": "9XM",
"logo": "https://i.imgur.com/fD7wLka.jpg", "type":"m38u",
"url": "https://d2q8p4pe5spbak.cloudfront.net/bpk-tv/9XM/9XM.isml/index.m3u8",
"category": "Music"
},
22
{
"name": "Aaj Tak",
"logo": "https://upload.wikimedia.org/wikipedia/commons/a/ab/AT-New-Logo-800x600.png",
"type":"m38u",
"url": "https://feeds.intoday.in/aajtak/api/aajtakhd/master.m3u8", "category":
"News"
},
{
"name": "Aaj Tak (560p)",
"logo": "https://upload.wikimedia.org/wikipedia/commons/a/ab/AT-New-Logo-800x600.png",
"type":"m38u",
"url": "https://lmil.live-s.cdn.bitgravity.com/cdn-live/_definst_/lmil/live/aajtak_app.smil/playlist.m3u8", "category":
"News"
},
{
"name": "Aathavan TV",
"logo": "https://i.imgur.com/IgwQ7o5.png",
"type":"m38u",
"language":"Tamil",
"url": "http://45.77.66.224:1935/athavantv/live/playlist.m3u8",
"category": "Entertainment"
},
{
"name": "ABP Ananda",
"logo": "https://tv.releasemyad.com/images/logo/20160108044853abp-ananada.jpg",
"type":"m38u",
"language":"Hindi",
"url": "https://abp-i.akamaihd.net/hls/live/765530/abpananda/master.m3u8", "category":
"News"
},
{
"name": "ABP Ananda(720p)",
"logo": "https://tv.releasemyad.com/images/logo/20160108044853abp-ananada.jpg", "type":"m38u",
"url": "https://d3pnfn2zxtq6km.cloudfront.net/out/v1/c77a35d9d4f74371a3cf0f214a9eb8c0/index.m3u8", "category":
"News"
},
{
"name": "ABP Asmita(324p)",
"logo": "https://upload.wikimedia.org/wikipedia/en/4/42/ABP_Asmita_Logo.png",
"type":"m38u",
"language":"Gujrati",
"url": "http://abpasmita-lh.akamaihd.net:80/i/abpasmita_1@77821/master.m3u8",
"category": "News"
},
{
"name": "ABP Asmita(720p)",
"logo": "https://upload.wikimedia.org/wikipedia/en/4/42/ABP_Asmita_Logo.png",
"type":"m38u",
"language":"Gujrati",
"url": "https://abp-i.akamaihd.net/hls/live/765532/abpasmita/master.m3u8",
23
"category": "News"
},
{
"name": "ABP Asmita",
"logo": "https://upload.wikimedia.org/wikipedia/en/4/42/ABP_Asmita_Logo.png",
"type":"m38u",
"language":"Gujrati",
"url": "https://abpasmita-lh.akamaihd.net/i/abpasmita_1@77821/master.m3u8", "category":
"News"
},
{
"name": "ABP News(324p)",
"logo": "https://static.abplive.in/wp-content/themes/abp-hindi/images/logo/hindiLogoD.png",
"type":"m38u",
"language":"English",
"url": "http://hindiabp-lh.akamaihd.net/i/hindiabp1new_1@192103/master.m3u8",
"category": "News"
},
{
"name": "ABP Majha",
"logo": "https://upload.wikimedia.org/wikipedia/en/5/5a/ABP_Majha_Logo.png",
"type":"m38u",
"language":"Hindi",
"url": "https://abp-i.akamaihd.net/hls/live/765531/abpmajha/master.m3u8", "category":
"News"
},
{
"name": "ABP News(720p)",
"logo": "https://static.abplive.in/wp-content/themes/abp-hindi/images/logo/hindiLogoD.png",
"type":"m38u",
"language":"English",
"url": "https://abp-i.akamaihd.net/hls/live/765529/abphindi/master.m3u8", "category":
"News"
},
];
}
else{
24
res.status('400').send('Auth fail');
}
});
module.exports = router;
11. Trending.js
const express = require('express');
const router = express.Router();
const resJson_trendingList = [
{
"name":"Godzilla vs Kong(Hindi audio)",
"logo":"https://images-na.ssl-images-amazon.com/images/I/81SAqNnNlfL._AC_SL1500_.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"Hindi",
"description":"Godzilla vs. Kong is a 2021 American monster film directed by Adam Wingard. A
sequel to Godzilla: King of the Monsters (2019) and Kong: Skull Island (2017), it is the fourth film
in Legendary's MonsterVerse. It is also the 36th film in the Godzilla franchise, the 12th film in the
King Kong franchise, and the fourth Godzilla film to be completely produced by a Hollywood studio.
The film stars Alexander Skarsgård, Millie Bobby Brown, Rebecca Hall, Brian Tyree Henry, Shun
Oguri, Eiza González, Julian Dennison, Lance Reddick, Kyle Chandler, and Demián Bichir. In the
film, Kong clashes with Godzilla as humans lure the ape into the Hollow Earth to retrieve a power
source for a weapon to stop Godzilla's mysterious rampages."
},
{
"name":"Blue call(720p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
xODA2MTA@._V1_FMjpg_UY682_.jpg
", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},
{
"name":"Panda Vs Aliens(720p)",
"logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"A group of aliens seek out to conquer new worlds and take particular notice of
Earth, after seeing satellite broadcasts of TV shows of a powerful panda, Pandy."
}
{
"name":"Blue call(360p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
25
"type":"m38u", "url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},
{
"name":"Godzilla vs Kong(Hindi audio)",
"logo":"https://images-na.ssl-images-amazon.com/images/I/81SAqNnNlfL._AC_SL1500_.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"Hindi",
"description":"Godzilla vs. Kong is a 2021 American monster film directed by Adam Wingard. A
sequel to Godzilla: King of the Monsters (2019) and Kong: Skull Island (2017), it is the fourth film
in Legendary's MonsterVerse. It is also the 36th film in the Godzilla franchise, the 12th film in the
King Kong franchise, and the fourth Godzilla film to be completely produced by a Hollywood studio.
The film stars Alexander Skarsgård, Millie Bobby Brown, Rebecca Hall, Brian Tyree Henry, Shun
Oguri, Eiza González, Julian Dennison, Lance Reddick, Kyle Chandler, and Demián Bichir. In the
film, Kong clashes with Godzilla as humans lure the ape into the Hollow Earth to retrieve a power
source for a weapon to stop Godzilla's mysterious rampages."
},
];
12. NewArrivals.js
const express = require('express');
const router = express.Router();
const resJson_newArrivalsList = [
{
"name":"Godzilla vs Kong(Hindi audio)",
"logo":"https://images-na.ssl-images-amazon.com/images/I/81SAqNnNlfL._AC_SL1500_.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"Hindi",
"description":"Godzilla vs. Kong is a 2021 American monster film directed by Adam Wingard. A
sequel to Godzilla: King of the Monsters (2019) and Kong: Skull Island (2017), it is the fourth film in
Legendary's MonsterVerse. It is also the 36th film in the Godzilla franchise, the 12th film in the King
26
fourth Godzilla film to be completely produced by a Hollywood studio. The film stars Alexander
Skarsgård, Millie Bobby Brown, Rebecca Hall, Brian Tyree Henry, Shun Oguri, Eiza González, Julian
Dennison, Lance Reddick, Kyle Chandler, and Demián Bichir. In the film, Kong clashes with Godzilla
as humans lure the ape into the Hollow Earth to retrieve a power source for a weapon to stop Godzilla's
mysterious rampages."
},{
"name":"Blue call(720p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
xODA2MTA@._V1_FMjpg_UY682_.jpg",
"type":"m38u", "url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},
{
"name":"Panda Vs Aliens(720p)",
"logo":"https://upload.wikimedia.org/wikipedia/en/a/ac/PandavsAliens.jpg",
"type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"A group of aliens seek out to conquer new worlds and take particular notice of Earth, after
seeing satellite broadcasts of TV shows of a powerful panda, Pandy."
},{
"name":"Blue call(360p)",
"logo":"https://m.media-
amazon.com/images/M/MV5BZjk4NzlhMjYtMjhlZi00MjIzLWFkZjAtMzBhMWZhNjZhNDExXkEyXkFqcGdeQXVyMjI
xODA2MTA@._V1_FMjpg_UY682_.jpg",
"type":"m38u", "url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"English",
"description":"Haylee, a local EMT suffering from PTSD, spends her days making split second
decisions with lives that hang in the balance. One night on a routine call, she is faced with a moral
decision, taking matters into her own hands and mercy kills a young woman. Her decision opens a
pandora's box that leads Haylee to blur the lines of her job responsibilities and wanting to help those in
need. Now, falling deeper and deeper into a rabbit hole, she gets caught up in a world of underground
drugs and a sadistic killer who's made her his next victim."
},{
"name":"Godzilla vs Kong(Hindi audio)",
"logo":"https://images-na.ssl-images-amazon.com/images/I/81SAqNnNlfL._AC_SL1500_.jpg", "type":"m38u",
"url":"https://llvod.mxplay.com/video/4fffa9037b466b90e5cf0022f0fb7ebc/6/hls/h264_baseline.m3u8",
"language":"Hindi",
"description":"Godzilla vs. Kong is a 2021 American monster film directed by Adam Wingard. A
sequel to Godzilla: King of the Monsters (2019) and Kong: Skull Island (2017), it is the fourth film
in Legendary's MonsterVerse. It is also the 36th film in the Godzilla franchise, the 12th film in the
King Kong franchise, and the fourth Godzilla film to be completely produced by a Hollywood studio.
The film stars Alexander Skarsgård, Millie Bobby Brown, Rebecca Hall, Brian Tyree Henry, Shun
Oguri, Eiza González, Julian Dennison, Lance Reddick, Kyle Chandler, and Demián Bichir.
27
router.get('/', async (req,res) => {
if(req.Auth){
try { res.status('200').send(resJson_newArrivalsList);
} catch (error) {
res.status('500').send('Server error');
}
}
else{
res.status('400').send('Auth fail');
}
});
module.exports = router;
28
4.2. Backend Coding
4.2.1 Widgets
1. main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:playsar/presentation/bloc/channel_page_bloc/channelpage_bloc.dart';import
'package:playsar/presentation/bloc/home_page_bloc/homepage_bloc.dart';
import 'package:playsar/presentation/bloc/movie_list_page_bloc/movielistpage_bloc.dart';import
'package:playsar/presentation/bloc/series_list_page/serieslistpage_bloc.dart';
import 'presentation/pages/splash_screen.dart';import
'utils/constants.dart';
void main() {
runApp(MyApp());
}
@override
Widget build(BuildContext context) {
return MultiBlocProvider( providers:
[
BlocProvider(create: (_) => HomePageBloc()..add(GetHomePageData())),
BlocProvider(create: (_) => ChannelPageBloc()..add(GetChannelListData())),
BlocProvider(create: (_) => MovieListPageBloc()),
BlocProvider(create: (_) => SeriesListPageBloc()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.dark,
theme: ThemeData(
fontFamily: 'Mukta',
scaffoldBackgroundColor: backgroundColor,
buttonColor: darkBlueColor,
accentColor: whiteColor,
iconTheme: IconThemeData(color: whiteColor),
appBarTheme: AppBarTheme(backgroundColor: darkGreyColor),
bottomNavigationBarTheme:
BottomNavigationBarThemeData(backgroundColor: darkGreyColor),hintColor:
whiteColor,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent)
)
)
),
title: 'playsar',
29
home: SplashScreen(),
),
);
}
}
2. splash_screen.dart
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import '../../utils/constants.dart';
import 'base_screen.dart';
@override
void initState() {
super.initState();
_animationController = AnimationController(vsync: this);
}
@override
Widget build(BuildContext context) {
final double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: ListView(
shrinkWrap: true,
children: [
Lottie.asset(
'assets/images/splash_screen_animation_lottie_json.json', width:
width,
height: width,
fit: BoxFit.fill,
controller: _animationController, onLoaded: (composition) {
_animationController
..duration = composition.duration
..forward().whenComplete(() => Navigator.of(context)
.pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return BaseScreen();
}), (route) => false));
}),
sized30, const
Text(
'playsar',
30
style: logoTextStyle,
textAlign: TextAlign.center,
)),
),
);
}
}
3. base_screen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@override
_BaseScreenState createState() => _BaseScreenState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(child: _screenList.elementAt(currentScreen)),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(icon:
Icon( CupertinoIcons.home,
),
label: 'Home'), BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.tv,
31
),
label: 'Tv Channel'),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.film,
),
label: 'Movies'),
BottomNavigationBarItem(
icon: Icon(
CupertinoIcons.tickets,
),
label: 'Series'),
],
backgroundColor: darkGreyColor,
currentIndex: currentScreen, onTap:
changeScreen, selectedItemColor:
darkBlueColor,
selectedLabelStyle: TextStyle(color: whiteColor),
unselectedItemColor: whiteColor,
);
4. home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../data/comming_soon/comming_soon.dart';import
'../widgets/comming_soon_banner.dart';
import '../../utils/constants.dart';
import '../bloc/home_page_bloc/homepage_bloc.dart';import
'../widgets/error_widget.dart';
import '../widgets/home_screen_banner.dart';
import '../widgets/horizontal_items_list.dart';
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {static
const titleGeneralError = 'Error occure';
static const titleNetworkError = 'No Internet Connection';
@override
void didChangeDependencies() {
super.didChangeDependencies();
_homePageBloc.add(GetHomePageData());
}
@override
void dispose() {
_homePageBloc.close();
super.dispose();
}
32
void retryFunction() async {
_homePageBloc.add(GetHomePageData());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<HomePageBloc, HomePageState>(bloc:
_homePageBloc,
builder: (context, state) {
if (state is HomePageLoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (state is HomePageLoadedState) {
return WidgetHomePageLoadedState(
newArrive: state.newArrivals, trendingList:
state.trendingList, featuredBanner:
state.featuredBanner,
commingSoonList: state.commingSoonList,
);
} else if (state is HomePageNoInternetState) {
return CustomeErrorWidget(
retryFunction: retryFunction,
errorTitle: titleNetworkError,
);
} else {
return CustomeErrorWidget(
retryFunction: retryFunction,
errorTitle: titleGeneralError,
);
},
),
);
}
const WidgetHomePageLoadedState({Key
key,
@required this.newArrive,
@required this.trendingList,
@required this.featuredBanner,
@required this.commingSoonList,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return SafeArea(
33
child: NestedScrollView(
physics: NeverScrollableScrollPhysics(),
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
pinned: true,
floating: true,
centerTitle: true,
expandedHeight: size.height * 0.8,
title: const Text(
appTitle,
style: logoTextStyle,
),
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: HomeScreenBanner(
size: size,
featuredBanner: featuredBanner,
),
),
),
];
},
body: ListView(
shrinkWrap: true,
children: [
sized10,
HorizontalItemsList(listTitle: titleTrending, list: trendingList),
sized10,
HorizontalItemsList(listTitle: titleNewArrive, list: newArrive),
sized10,
Container( child:
Center(
child: const Text(
'Comming Soon',
style: commingSoonTitleStyle,
))),
sized20,
CommingSoonBanner(size: size, commingSoonList: commingSoonList),
sized20
],
)),
);
}
5. channel_page
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../utils/constants.dart';
import '../../bloc/channel_page_bloc/channelpage_bloc.dart';
import '../../widgets/channel_screen.dart';
import '../../widgets/error_widget.dart';
34
@override
_ChannelPageState createState() => _ChannelPageState();
}
ChannelPageBloc _channelPageBloc;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_channelPageBloc = ChannelPageBloc()..add(GetChannelListData());
}
@override
void dispose() {
_channelPageBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: const Text(
'Tv Channel',
style: logoTextStyle,
),
centerTitle: true,
),
body: BlocConsumer<ChannelPageBloc, ChannelPageState>(bloc:
_channelPageBloc,
listener: (context, state) {},
builder: (context, state) {
if (state is ChannelPageLoadingState) {
return const Center(child: const CircularProgressIndicator());
} else if (state is ChannelPageLoadedState) {
return ChannelScreen(size: size, channelList: state.channelList);
} else if (state is ChannelPageNoInternetState) {
return CustomeErrorWidget(
retryFunction: retryFunction,
errorTitle: titleNetworkError,
);
} else {
return CustomeErrorWidget(
retryFunction: retryFunction,
errorTitle: titleGeneralError,
);},
35
6. channel_page
import 'package:flutter/material.dart';
import 'package:playsar/presentation/pages/movies/movies_list_page.dart';
import '../../../data/movies/movies_categories.dart';
import '../../../utils/constants.dart';
import '../../widgets/categories_widget.dart';
@override
_MoviesCategoriesPageState createState() => _MoviesCategoriesPageState();
}
@override
void initState() {
super.initState();
}
return categoryNameToLowerCase.contains(searchTextToLowerCase);
}).toList();
setState(() {
this.movieCateroiesList = searchedChannels;
});
}
@override
Widget build(BuildContext context) {
return Scaffold( appBar:
AppBar( centerTitle:
true, title: const Text(
'Movies Categories',
style: logoTextStyle,
),
),
body: CategoriesWidget(
onSearchBarValueChangeFunction: onSearchBarValueChangeFunction,categoriesList:
movieCateroiesList,
onTapNavigate: (categoryUrl, categoryName) {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return MovieListPage(
categoryUrl: categoryUrl, categoryName: categoryName);
}));
},
));
36
7. movies_category_page.dart
import 'package:flutter/material.dart';
import 'package:playsar/presentation/pages/movies/movies_list_page.dart';
import '../../widgets/categories_widget.dart';
@override
movieCategories;
@override
void initState() {
super.initState();
searchTextToLowerCase = searchText.toLowerCase();
return categoryNameToLowerCase.contains(searchTextToLowerCase);
}).toList();
37
setState(() {
this.movieCateroiesList = searchedChannels;
});
@override
logoTextStyle,
),
),
body: CategoriesWidget(
onSearchBarValueChangeFunction: onSearchBarValueChangeFunction,categoriesList:
movieCateroiesList,
Navigator.of(context).push(MaterialPageRoute(builder: (context)
{
return MovieListPage(
}));
},
));
8. series_category_page.dart
import 'package:flutter/material.dart';
38
import '../../../data/series/series_categories.dart';import '../../../utils/constants.dart';
import '../../widgets/categories_widget.dart';import
'series_list_page.dart';
@override
seriesCategories;
@override
void initState() {
super.initState();
searchTextToLowerCase = searchText.toLowerCase();
return categoryNameToLowerCase.contains(searchTextToLowerCase);
}).toList();
setState(() {
this.seriesCateroiesList = searchedChannels;
});
39
@override
logoTextStyle,
),
),
body: CategoriesWidget(
onSearchBarValueChangeFunction: onSearchBarValueChangeFunction,categoriesList:
seriesCateroiesList,
Navigator.of(context).push(MaterialPageRoute(builder: (context)
{
return SeriesListPage(
}));
},
));
9. app_widgets.dart
//@dart=2.9
import 'package:cached_network_image/cached_network_image.dart';import
'package:flutter/material.dart';
class AppWidget {
40
BoxFit fit,
Color backgroundColor,
bool circle,
String error}) {
return Builder(builder: (ctx) { if
(url == null || url.isEmpty) {if
(circle != null && circle) {
return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(100)),child:
Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
));
}
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
);
} else {
if (circle != null && circle) {
return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(100)),child :
CachedNetworkImage(
imageUrl: url ?? defaultImageURL,
width: width,
height: height,
fit: fit,
placeholder: (context,url){
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
);
},
errorWidget: (context, url, error) {
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
41
width: width,
height: height,
),
),
);
},
),
);
}
return CachedNetworkImage(
imageUrl: url ?? defaultImageURL,
width: width,
height: height,
fit: fit,
placeholder: (context,url){
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
error ?? "assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
);
},
errorWidget: (context, url, error) {
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
);
},
);
}
})
42
static Widget profileImageView(String url,
{double height,
double width,
BoxFit fit,
Color backgroundColor,
bool circle,
String error}) {
return Builder(builder: (ctx) { if
(url == null || url.isEmpty) {if
(circle != null && circle) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(100)),
child: Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
"assets/images/placeholder.jpeg",
fit: BoxFit.fill,
width: width,
height: height,
),
),
));
}
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
);
} else {
if (circle != null && circle)
{return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(100)),
child: CachedNetworkImage(
imageUrl: url ?? defaultImageURL,
width: width,
height: height,
fit: fit,
placeholder: (context,url){
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
);
},
errorWidget: (context, url, error) {
return Container(
43
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",fit:
BoxFit.fill,
width: width,
height: height,
),
),
);
},
),
);
}
return CachedNetworkImage(
imageUrl: url ?? defaultImageURL,
width: width,
height: height,
44
fit: fit,
placeholder: (context,url){
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
"assets/images/placeholder.jpeg",
fit: BoxFit.fill,
width: width,
height: height,
),
),
);
},
errorWidget: (context, url, error) {
return Container(
color: backgroundColor ?? Colors.transparent,
child: Center(
child: Image.asset(
'assets/images/placeholder.jpeg',
fit: BoxFit.fill,
width: width,
height: height,
),
),
);
},
}
);
})
;
}}
10. categories_widgets.dart
import 'package:flutter/material.dart';
import '../../utils/constants.dart';import
'Grid_Card.dart';
import 'search_bar.dart';
45
return ListView(
children: [
sized10,
SearchBar(
searchHint: searchCategories,
onchangeFunction: onSearchBarValueChangeFunction,
),
sized10,
GridView.builder(
physics: NeverScrollableScrollPhysics(),shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: categoriesList.length,itemBuilder: (context,
index) {
return GestureDetector(
onTap: () =>
onTapNavigate(categoriesList[index].categoryUrl,
categoriesList[index].categoryName),child: GridCard(
name: categoriesList[index].categoryName,
logoUrl: categoriesList[index].categoryLogo,
),
);
}),
],
);
}
}
11. channel_card.dart
StatelessWidget {
final String channelName;final String
channelLogo;final Size size;
const ChannelCard(
{Key key,
@required this.channelName,@required
this.channelLogo,@required this.size})
: super(key: key);
46
Widget build(BuildContext context) {
return Container(height:
100.0,
width: 100.0, child:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Container( decoration:
BoxDecoration(
borderRadius: BorderRadius.circular(20.0),image:
DecorationImage(
image: NetworkImage(channelLogo), fit: BoxFit.fill)),
),
),
],
),
);
}
}
12. channel_screen.dart
import 'package:flutter/material.dart';
import 'package:playsar/presentation/widgets/Grid_Card.dart';
import '../../data/channels/channel.dart';import
'../../utils/constants.dart'; import
'../pages/view_media_page.dart'; import 'channel_card.dart';
import 'search_bar.dart';
return channelNameToLowerCase.contains(searchTextToLowerCase);
}).toList();
setState(() {
this.channels = searchedChannels;
});
}
@override
Widget build(BuildContext context) {return
SingleChildScrollView(
child: Column(
children: [
sized10,
SearchBar(
searchHint: searchChannels,
onchangeFunction: onSearchBarValueChangeFunction,
),
sized10,
Padding(
padding: const EdgeInsets.all(20.0),child:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2,
crossAxisSpacing: 20.0,
mainAxisSpacing: 20.0),
physics: NeverScrollableScrollPhysics(),shrinkWrap: true,
itemCount: channels.length, itemBuilder: (context,
index) {
return InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context)
{
channels[index].url);
}),
48
return ViewMediaPage(source:
}));
},
child: GridCard(
name:
channels[ind
ex].name,
logoUrl:
channels[ind
ex].logo,
));
],
),
);
}
49
13. coming_soon_banner.dart
import 'package:flutter/material.dart';
import 'package:playsar/data/comming_soon/comming_soon.dart';
@override
Widget build(BuildContext context) {return
Container(
height: size.height * 0.25,
child: Center(
child: ListView.builder( scrollDirection:
Axis.horizontal, physics:
BouncingScrollPhysics(), itemCount:
commingSoonList.length,itemBuilder: (context,
index) {
return Container(
margin: const EdgeInsets.symmetric(horizontal:10.0),width: size.width * 0.8,
height: size.height * 0.25,child: Center(
child: Text(commingSoonList[index].name,
style: const TextStyle(
color: Colors.white, fontWeight:
FontWeight.w600,fontSize: 24.0)),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),image:
DecorationImage(
image: NetworkImage(commingSoonList[index].logo),fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.2), BlendMode.dstATop),
),
),
);
}),
),
50
14. grid_card.dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:playsar/presentation/widgets/app_widget.dart';import
'../../utils/constants.dart';
const GridCard(
{Key key,
@required this.name,
@required this.logoUrl})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8.0),
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
gradient:
LinearGradient(
begin: Alignment.topLeft, end:
Alignment.bottomRight,
colors: [darkBlueColor , darkGreyColor]),
),
child: Column(children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10.0),
bottomLeft: Radius.circular(10.0),
),
),
child: AppWidget.imageView(
logoUrl,
fit: BoxFit.fill,
),
),
),
sized5,
RichText(
text: TextSpan(
text: name,
style: listTitleStyle
51
sized5
]),
);
}
15. home_screen_banner.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../utils/constants.dart';
import '../pages/view_media_page.dart';
@override
Widget build(BuildContext context) {
return Container(
height: size.height * 0.7,
width: double.infinity,
child: Stack(
children: [
Container(
height: size.height,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(featuredBanner.logo),fit:
BoxFit.fill,
)),),
Positioned(
left: 0.0,
top: size.height * 0.7,
child: Container(
width: size.width,
child: Center(
child: GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) { return
ViewMediaPage(source: featuredBanner.url);
}));},
child: Container(
decoration: BoxDecoration(
color: whiteColor, border:
Border.all(
color: Colors.black, style:
BorderStyle.solid,
52
),
borderRadius: BorderRadius.circular(20.0),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(.7),
blurRadius: 3.0,
spreadRadius: 0.5)
]),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const [
const Padding(
padding: const EdgeInsets.only(left: 10.0),
child: const Icon(
CupertinoIcons.play,color:
Colors.black,
),
),
const Padding(
padding: const EdgeInsets.only(right: 10.0),
child: const Text(
watch,
style: TextStyle(fontWeight: FontWeight.w700),
),
),
],
),
),
),
)),
],
),
);
}
}
16. horizontal_items_list.dart
import 'package:flutter/material.dart';
import '../../utils/constants.dart';
import '../pages/view_media_page.dart';
17. list_screen.dart
import 'package:flutter/material.dart';
54
import '../../utils/constants.dart';
import 'Grid_Card.dart';
import 'search_bar.dart';
@override
_ListScreenState createState() => _ListScreenState();
}
return listItemNameToLowerCase.contains(searchTextToLowerCase);
}).toList();
setState(() {
this.itemList = searched;
});
}
@override
Widget build(BuildContext context) {
return CustomScrollView(slivers: [
const SliverToBoxAdapter(
child: SizedBox(
height: 10.0,
),
),
SliverToBoxAdapter(
child: SearchBar(
searchHint: widget.searchHint,
onchangeFunction: onSearchBarValueChangeFunction)),const
SliverToBoxAdapter(
child: SizedBox(
height: 10.0,
),
),
55
delegate: SliverChildBuilderDelegate(
(context, index) {
return GestureDetector(
onTap: () => widget.navigationFunction(itemList[index]),
child: GridCard(
name: itemList[index].name,
logoUrl: itemList[index].logo,
),
);
},
childCount: itemList.length,
),
),
]);
}
}
18. search_bar.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../utils/constants.dart';
@override
void initState() {
super.initState();
textEditingController = TextEditingController();
}
@override
void dispose() { textEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container( width:
double.infinity,height:
70.0,
margin: const EdgeInsets.symmetric(horizontal: 10.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(.05),
56
borderRadius: BorderRadius.circular(50.0),
),
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),child:
TextField(
enableSuggestions: true,
controller: textEditingController,
cursorColor: darkBlueColor,
style: TextStyle(color: Colors.white.withOpacity(.8)),
decoration: InputDecoration(
focusColor: darkBlueColor,
border: InputBorder.none,
hintText: widget.searchHint,
prefixIcon: InkWell(
child: Icon(CupertinoIcons.search, color: darkBlueColor),
onTap: () {
FocusScope.of(context).unfocus();
},
),
suffixIcon: textEditingController.text.isNotEmpty
? InkWell(
child: Icon(
CupertinoIcons.clear,
color: Colors.redAccent,
),
onTap: () {
textEditingController.clear();
widget.onchangeFunction('');
FocusScope.of(context).requestFocus(FocusNode());
},
)
: null),
onChanged: widget.onchangeFunction,
),
);
}
}
19. series_season_display_card.dart
import 'package:flutter/material.dart';
import 'package:playsar/data/series/episode.dart';
import '../../data/series/seasons.dart';
import '../../utils/constants.dart';
57
Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image: NetworkImage(seasons!=null ? seasons.seasonLogo: episode.episodeLogo),
fit: BoxFit.cover)),
),
const SizedBox(
width: 10.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
seasons!=null ? seasons.seasonName: episode.episodeName,style:
TextStyle(
color: whiteColor,
fontWeight: FontWeight.w700,
fontSize: 26.0),
),
Text(
seasons!=null ? seasons.seasonDescription: episode.episodeDescription,style:
TextStyle(
color: Colors.white54,
fontWeight: FontWeight.w300,
fontSize: 20.0),
),
],
),
],
),
);
}
}
20. widget_information_box.dart
import 'package:flutter/material.dart';
import '../../utils/constants.dart';
@override
Widget build(BuildContext context) {return
Container(
width: width,
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal:10.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.05),
),
child: RichText( text:
TextSpan(
style: const TextStyle(fontSize:
15.0, color: whiteColor,
),
children: <TextSpan>[
TextSpan(text: title),TextSpan(
text: text,
style: const TextStyle( fontWeight:
FontWeight.bold,
),
),
],
),
),
);
}
}
59
4.3. Data
import 'dart:convert';
import 'package:flutter/foundation.dart';import
'language.dart';
class Channel {
final String name;
final String logo;
final String url;
final String category;
});
Channel copyWith({
String name, String
logo,
String url,
String category,
List<Language> languages,
}) {
return Channel(
name: name ?? this.name,
logo: logo ?? this.logo,
url: url ?? this.url,
category: category ?? this.category,
);
}
};
}
);
}
@override
String toString() {
return 'Channel(name: $name, logo: $logo, url: $url, category: $category)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode {
return name.hashCode ^
logo.hashCode ^
url.hashCode ^
category.hashCode;
}
}
import 'dart:convert';
import 'package:flutter/cupertino.dart';
class Language {
final String code;
final String name;
const Language({
@required this.code,
@required this.name,
});
Language copyWith({
String code,
String name,
}) {
return Language(
code: code ?? this.code,
name: name ?? this.name,
);
}
@override
String toString() => 'Language(code: $code, name: $name)';
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode => code.hashCode ^ name.hashCode;
}
2. comming_soon.dart
import 'dart:convert';
class CommingSoon {
final String name;
final String logo;
final String releaseDate;
const CommingSoon(
this.name,
this.logo,
this.releaseDate,
);
CommingSoon copyWith({
String name,
String logo,
String releaseDate,
}) {
return CommingSoon(
name ?? this.name,
logo ?? this.logo,
releaseDate ?? this.releaseDate,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode => name.hashCode ^ logo.hashCode ^ releaseDate.hashCode;
}
3. Movies
import 'dart:convert';
import 'package:flutter/cupertino.dart';
class Movie {
final String name;
final String logo;
final String url;
final String language;
final String description;
const Movie({
@required this.name,
@required this.logo,
@required this.url,
@required this.language,
@required this.description,
});
Movie copyWith({
String name,
String logo,
String url,
String language,
String description,
}) {
return Movie(
name: name ?? this.name,
logo: logo ?? this.logo,
url: url ?? this.url,
63
language: language ?? this.language,
description: description ?? this.description,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode {
return name.hashCode ^
logo.hashCode ^
url.hashCode ^
language.hashCode ^
description.hashCode;
}
}
import 'package:flutter/foundation.dart';
class MoviesCategories {
64
final String categoryName;final String
categoryLogo;const
MoviesCategories(
this.categoryLogo, @required
this.categoryName});
'actionMovies',categoryLogo:
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4
NwjIBKuOMjVi4ou8UR'),
MoviesCategories(
'adventureMovies',categoryLogo:
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4
NwjIBKuOMjVi4ou8UR'),
MoviesCategories( categoryName:
'Animated',
categoryUrl: 'animatedMovies',
categoryLogo:
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4
NwjIBKuOMjVi4ou8UR'),
MoviesCategories( categoryName:
'Comedies',
categoryUrl: 'comediesMovies',categoryLogo:
65
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
MoviesCategories( categoryName:
'Dramas',
categoryUrl: 'dramasMovies',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
MoviesCategories( categoryName:
'Horror',
categoryUrl: 'horrorMovies',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
MoviesCategories(
'musicalMovies',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
categoryUrl: 'otherMovies',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
MoviesCategories( categoryName:
'RealLife',
categoryUrl: 'reallifeMovies',
categoryLogo:
66
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
MoviesCategories( categoryName:
'Romantic',
categoryUrl: 'romanticMovies',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
];
4. Series
import 'dart:convert';
import 'package:flutter/cupertino.dart';
class Episode {
final String episodeName;
final String episodeDescription;
final String episodeUrl;
final String episodeLogo;
const Episode({
@required this.episodeName,
@required this.episodeDescription,
@required this.episodeUrl, @required
this.episodeLogo,
});
Episode copyWith({
String episodeName,
String episodeDescription,
String episodeUrl,
String episodeLogo,
}) {
return Episode(
episodeName: episodeName ?? this.episodeName, episodeDescription:
episodeDescription ?? this.episodeDescription,episodeUrl: episodeUrl ??
this.episodeUrl,
episodeLogo: episodeLogo ?? this.episodeLogo,
);
}
67
'episodeLogo': episodeLogo,
};
}
@override
String toString() {
return 'Episode(episodeName: $episodeName, episodeDescription: $episodeDescription,
episodeUrl: $episodeUrl, episodeLogo: $episodeLogo)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode {
return episodeName.hashCode ^
episodeDescription.hashCode ^
episodeUrl.hashCode ^
episodeLogo.hashCode;
}
}
//seasons
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:playsar/data/series/episode.dart';class
Seasons {
final String seasonName;
final String seasonDescription;
final String seasonLogo;
final List<Episode> episodes;
const Seasons({
@required this.seasonName,
@required this.seasonDescription,
@required this.seasonLogo,
@required this.episodes,
68
});
Seasons copyWith({
String seasonName,
String seasonDescription,
String seasonLogo,
List<Episode> episodes,
}) {
return Seasons(
seasonName: seasonName ?? this.seasonName, seasonDescription:
seasonDescription ?? this.seasonDescription,seasonLogo: seasonLogo ??
this.seasonLogo,
episodes: episodes ?? this.episodes,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode {
return seasonName.hashCode ^
seasonDescription.hashCode ^
seasonLogo.hashCode ^
episodes.hashCode;
69
}
}
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'seasons.dart';
class Series {
final String name;
final String logo;
final List<Seasons> seasons;
final String language;
final String description;
Series({
@required this.name,
@required this.logo,
@required this.seasons,
@required this.language,
@required this.description,
});
Series copyWith({
String name,
String logo,
List<Seasons> seasons,
String language,
String description,
}) {
return Series(
name: name ?? this.name,
logo: logo ?? this.logo,
seasons: seasons ?? this.seasons, language:
language ?? this.language, description:
description ?? this.description,
);
}
70
factory Series.fromJson(String source) => Series.fromMap(json.decode(source));
@override
String toString() {
return 'Series(name: $name, logo: $logo, seasons: $seasons, language: $language, description:
$description)';
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@override
int get hashCode {
return name.hashCode ^
logo.hashCode ^
seasons.hashCode ^
language.hashCode ^
description.hashCode;
}
}
import 'package:flutter/foundation.dart';
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4NwjIBKuOMjVi
4ou8UR'),
SeriesCategories( categoryName:
'Adventure', categoryUrl:
'adventureSeries',categoryLogo:
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4NwjIBKuOMjVi
4ou8UR'),
SeriesCategories( categoryName:
'Animated', categoryUrl:
'animatedSeries',categoryLogo:
71
'https://t3.gstatic.com/images?q=tbn:ANd9GcQzBPeJBL1nrbE44py9eA0PFWzRQjQlW4NwjIBKuOMjVi
4ou8UR'),
SeriesCategories( categoryName:
'Comedies', categoryUrl:
'comediesSeries',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories( categoryName:
'Dramas', categoryUrl:
'dramasSeries',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories(
categoryName: 'Horror',
categoryUrl: 'horrorSeries',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories( categoryName:
'Musical', categoryUrl:
'musicalSeries',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories(
categoryName: 'Other',
categoryUrl: 'otherSeries',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories(
categoryName: 'RealLife',
categoryUrl: 'reallifeSeries',
categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
SeriesCategories( categoryName:
'Romantic', categoryUrl:
'romanticSeries',categoryLogo:
'https://images.unsplash.com/photo-1509248961158-
e54f6934749c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-
1.2.1&auto=format&fit=crop&q=80'),
];
72
4.4. Domain
network_repository.dart:
import 'dart:convert';
import '../../data/channels/channel.dart';
import '../../data/comming_soon/comming_soon.dart';import
'../../data/movies/movies.dart';
import '../../data/series/series.dart'; import
'../../utils/network_constants.dart';
class NetworkRepo {
static final client = http.Client();
static const Map<String, String> tokenData = { "Content-
type": "application/x-www-form-urlencoded",
"Authorization": NetworkConstants.token
};
parsed.forEach((_mapElement) {
channelList.add(Channel.fromMap(_mapElement));
});
return channelList;
} catch (e) {
print(e.toString());
throw (e);
}
}
///this is for home page section
//get featured banner
Future<Movie> getFeaturedBanner() async {try
{
final response = await client.get(
Uri.parse('${NetworkConstants.baseUrl}featuredBanner'), headers:
tokenData);
return movie;
} catch (e) {
throw (e);
}
parsed.forEach((_mapElement) {
trendingList.add(Movie.fromMap(_mapElement));
});
return trendingList;
} catch (e) {
throw (e);
}
}
parsed.forEach((_mapElement) {
newArrivals.add(Movie.fromMap(_mapElement));
});
return newArrivals;
} catch (e) {
throw (e);
}
}
//comming_soon
Future<List<CommingSoon>> getCommingSoonList() async {
List<CommingSoon> commingsoonList = [];
try {
final response = await client.get(
Uri.parse('${NetworkConstants.baseUrl}commingsoon'), headers:
tokenData);
List parsed = jsonDecode(response.body).cast<Map<String, dynamic>>();
parsed.forEach((commingsoonElement) {
commingsoonList.add(CommingSoon.fromMap(commingsoonElement));
});
return commingsoonList;
} catch (e) {
print(e.toString());
throw (e);
}
}
74
List<Movie> movieList = [];
try {
final response = await client.get(
Uri.parse('${NetworkConstants.baseUrl}$categoryUrl'),
headers: tokenData);
List parsed = jsonDecode(response.body).cast<Map<String, dynamic>>();
parsed.forEach((_mapElement) {
movieList.add(Movie.fromMap(_mapElement));
});
return movieList;
} catch (e) {
throw (e);
}
}
///series page
parsed.forEach((_mapElement) { seriesList.add(Series.fromMap(_mapElement));
});
return seriesList;
} catch (e) {
throw (e);
}
}
}
4.5 .Bloc
1. home_page_bloc
import 'dart:async';
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import '../../../data/comming_soon/comming_soon.dart';
import '../../../data/movies/movies.dart';
import '../../../domain/repositories/network_repo.dart';
75
class HomePageBloc extends Bloc<HomePageEvent, HomePageState> {
static final networkRepo = NetworkRepo();
HomePageBloc() : super(HomePageLoadingState());
@override
Stream<HomePageState> mapEventToState(
HomePageEvent event,
) async* {
if (event is GetHomePageData) {
yield HomePageLoadingState();try
{
// print(DateTime.now().toString());
// final value = await Future.wait(
// [networkRepo.trendingList(), networkRepo.getFeaturedBanner(),networkRepo.newArrivalList() ,
networkRepo.getCommingSoonList()]);
// value.forEach((element) {
// print(element.toString());
// element.forEach((subelement) {
// print(subelement.toString());
// });
// });
// print(DateTime.now().toString());
final List trendingList = await networkRepo.trendingList();
final Movie featuredBanner = await networkRepo.getFeaturedBanner();final
List newArrivals = await networkRepo.newArrivalList();
final List<CommingSoon> commingSoonList =
await networkRepo.getCommingSoonList();
// print(DateTime.now().toString());
yield HomePageLoadedState(
trendingList: trendingList,
featuredBanner: featuredBanner,
newArrivals: newArrivals,
commingSoonList: commingSoonList);
} on IOException {
yield HomePageNoInternetState();
} catch (e) {
print(e.toString());
yield HomePageErrorState();
}
}
part of 'homepage_bloc.dart';
@override
List<Object> get props => [];
}
part of 'homepage_bloc.dart';
76
abstract class HomePageState extends Equatable {const
HomePageState();
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
2. movie_list_bloc
import 'dart:async';
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import '../../../data/movies/movies.dart';
import '../../../domain/repositories/network_repo.dart';
part 'movielistpage_event.dart';
77
class MovieListPageBloc extends Bloc<MovieListPageEvent, MovieListPageState> {
MovieListPageBloc() : super(MovieListPageLoadingState());
@override
Stream<MovieListPageState> mapEventToState(
MovieListPageEvent event,
) async* {
yield MovieListPageLoadingState();
if (event is GetMovieListBaseOnCategory) {try
{
final List<Movie> moviesList =
await NetworkRepo().getMovieCategoryList(event.categoryUrl);yield
MovieListPageLoadedState(moviesList: moviesList);
} on IOException {
yield MovieListPageNoInternetState();
} catch (e) {
yield MovieListPageErrorState();
}
}
}
part of 'movielistpage_bloc.dart';
@override
List<Object> get props => [];
}
@override
List<Object> get props => [categoryUrl];
}
part of 'movielistpage_bloc.dart';
@override
List<Object> get props => [];
}
class MovieListPageLoadingState extends MovieListPageState {const
MovieListPageLoadingState();
@override
List<Object> get props => [];
}
class MovieListPageLoadedState extends MovieListPageState {final
List<Movie> moviesList;
const MovieListPageLoadedState({@required this.moviesList});
@override
78
List<Object> get props => [moviesList];
}
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
3. series_list_bloc
import 'dart:async';
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import '../../../data/series/series.dart';
import '../../../domain/repositories/network_repo.dart';
part 'serieslistpage_event.dart';part
'serieslistpage_state.dart';
class SeriesListPageBloc
extends Bloc<SeriesListPageEvent, SeriesListPageState> {
SeriesListPageBloc() : super(SeriesListPageLoadingState());
@override
Stream<SeriesListPageState> mapEventToState(
SeriesListPageEvent event,
) async* {
yield SeriesListPageLoadingState();
if (event is GetSeriesListBaseOnCategory) {try
{
final List<Series> seriesList =
await NetworkRepo().getSeriesCategoryList(event.categoryUrl);
yield SeriesListPageLoadedState(seriesList: seriesList);
} on IOException {
yield SeriesListPageNoInternetState();
} catch (e) {
yield SeriesListPageErrorState();
}
}
}
}
79
const SeriesListPageEvent();
@override
List<Object> get props => [];
}
@override
List<Object> get props => [categoryUrl];
}
part of 'serieslistpage_bloc.dart';
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
class SeriesListPageErrorState extends SeriesListPageState {
const SeriesListPageErrorState();
@override
List<Object> get props => [];
}
4. channel_page_bloc
import 'dart:async';
import 'dart:io';
80
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import '../../../data/channels/channel.dart';
import '../../../domain/repositories/network_repo.dart';
part 'channelpage_event.dart';
part 'channelpage_state.dart';
@override
Stream<ChannelPageState> mapEventToState(
ChannelPageEvent event,
) async* {
if (event is GetChannelListData) {
yield ChannelPageLoadingState();try
{
final List<Channel> channelList =
await NetworkRepo().indianChannelList();
yield ChannelPageLoadedState(channelList: channelList);
} on IOException {
yield ChannelPageNoInternetState();
} catch (e) {
print(e.toString());
yield ChannelPageErrorState();
}
}
}
}
part of 'channelpage_bloc.dart';
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
part of 'channelpage_bloc.dart';
@override
List<Object> get props => [];
}
81
@override
List<Object> get props => [];
}
@override
List<Object> get props => [channelList];
}
@override
List<Object> get props => [];
}
@override
List<Object> get props => [];
}
82
CHAPTER 5
DIRECTORY STRUCTURE
5.1 D structure
83
5.2 Front-End Directory Structure:
84
5.3 Back end directory structure
85
CHAPTER 6
TESTING AND SCREENSHOTS
6.1 Testing
Testing is the integral part of any System Development Life Cycle insufficient and interested
application tends to crash and result in loss of economic and manpower investment besides user’s
dissatisfaction and downfall of reputation.
The first step of system testing is to develop the plan that all aspect of system. Complements,
Correctness, Reliability and Maintainability.
Software is to be tested for the best quality assurance, an assurance that system meets the specification
and requirement for its intended use and performance.
System testing is the most useful practical process of executing the program with the implicit
intention of finding errors that makes the program fail.
Unit tests
A unit test tests a single function, method, or class. The goal of a unit test is to verify the correctness
of a unit of logic under a variety of conditions. External dependencies of the unit under test are generally
mocked out. Unit tests generally don’t read from or write to disk, render to screen, or receive user actions
from outside the process running the test. For more information regarding unit tests, you can view the
following recipes or run flutter test -- help in your terminal.
Widget tests
A widget test (in other UI frameworks referred to as component test) tests a single widget. The goal
of a widget test is to verify that the widget’s UI looks and interacts as expected. Testing a widget involves
multiple classes and requires a test environment that provides the appropriate widget lifecycle context.
For example, the Widget being tested should be able to receive and respond to user actions and events,
perform
layout, and instantiate child widgets. A widget test is therefore more comprehensive than a unit test.
However, like a unit test, a widget test’s environment is replaced with an implementation much simpler
than a full-blown UI system.
Integration tests
An integration test tests a complete app or a large part of an app. The goal of an integration test is
to verify that all the widgets and services being tested work together as expected. Furthermore, you can
use integration tests to verify your app’s performance.
86
Generally, an integration test runs on a real device or an OS emulator, such as iOS Simulator or
Android Emulator. The app under test is typically isolated from the test driver code to avoid skewing the
results.
6.3 Screenshots
87
88
89
90
91
92
93
94
95
96
7. Conclusion
This software is efficient to provide entertainment to user by her features movies list with
category , channel list, web series list and live telecast .
While streaming services are becoming more popular, users are still gearing towards free
streaming services like Hotstar, which takes away the amount of revenue artists are making.
However, streaming has proven to be beneficial for independent artists who are looking to get their
name more known. Streaming has also been proven to be more convenient for consumer as it is
faster and can be made available through any mobile device. Although streaming has caused a
decrease in revenue for the music industry, the use of pirated music/video has declined, which was
a major issue for the industry during the digital download era. Even more people are using free
options of music/video streaming over paid subscriptions, the amount of revenue streaming services
are earning is steadily increasing. Streaming is likely to be around for a while, but the music/video
industry should be prepared for the next change in technology
97
8. Reference
1. https://docs.flutter.dev/
2. https://medium.com/@subhashchandrashukla
3. https://www.amazon.in/Flutter-Complete-Reference-Create-beautiful-ebook/dp/B08KHKK8TR
4.https://www.linkedin.com/redir/redirect?url=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttps%2Fsubhashdev121%2Egithub%2Eio%2Fs
ubhash%2F%23%2F&urlhash=BoTA&trk=public_profile_topcard-website
98