├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── dependabot.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── composer.json ├── screenshots └── channel_list.jpg └── src ├── Controllers ├── CdnController.php ├── ChannelController.php ├── ChannelListM3UController.php ├── GroupController.php └── UrlController.php ├── Dashs ├── Cdns.php ├── Channels.php └── Groups.php ├── IPTVProvider.php ├── Middleware └── PublicCdnMiddleware.php ├── Model ├── IPTVCdn.php ├── IPTVChannel.php ├── IPTVChannelGroup.php └── IPTVUrl.php ├── database └── migrations │ ├── 2017_09_13_131302_create_iptv_channel_groups.php │ ├── 2017_09_13_133037_create_iptv_channels.php │ ├── 2021_08_18_115119_create_iptv_cdns_table.php │ └── 2021_08_18_225941_create_iptv_urls_table.php ├── resources ├── menu.json ├── translations │ ├── br.json │ └── en.json └── views │ ├── cdn.blade.php │ ├── cdn_dash.blade.php │ ├── cdn_list.blade.php │ ├── channel.blade.php │ ├── channel_dash.blade.php │ ├── channel_list.blade.php │ ├── group.blade.php │ ├── group_dash.blade.php │ ├── group_list.blade.php │ └── list_M3U.blade.php └── routes.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [eufelipemateus] 4 | #patreon: # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | liberapay: eufelipemateus 7 | custom: ['https://www.paypal.com/donate?hosted_button_id=WV4K7MQZY5W3N'] 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: eufelipemateus 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature]" 5 | labels: enhancement 6 | assignees: eufelipemateus 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: composer 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | eu@felipemateus.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | . 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | . Translations are available at 128 | . 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Felipe Mateus Rocha Martins 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel IPTV Channels - FelipeMateus\IPTVChannels 2 | 3 | # Atention! This package was moved to laravel-iptv-cms 4 | 5 | 6 | [![Latest Stable Version](http://poser.pugx.org/felipemateus/iptv-channels/v)](https://packagist.org/packages/felipemateus/iptv-channels) [![Total Downloads](http://poser.pugx.org/felipemateus/iptv-channels/downloads)](https://packagist.org/packages/felipemateus/iptv-channels) [![Latest Unstable Version](http://poser.pugx.org/felipemateus/iptv-channels/v/unstable)](https://packagist.org/packages/felipemateus/iptv-channels) [![License](http://poser.pugx.org/felipemateus/iptv-channels/license)](https://packagist.org/packages/felipemateus/iptv-channels) [![PHP Version Require](http://poser.pugx.org/felipemateus/iptv-channels/require/php)](https://packagist.org/packages/felipemateus/iptv-channels) 7 | 8 | This is a libary package create to generate and control channel list m3u8 using php Laravel this libary work to [iptv-cms](https://github.com/eufelipemateus/laravel-iptv-cms). 9 | 10 | ![Screenshot Feipe Mateus IPTV Channels](/screenshots/channel_list.jpg?raw=true) 11 | 12 | ## Instaling 13 | 14 | Tested in Laravel 9.0. 15 | 16 | ### Run the command below in root to install the package in your project 17 | 18 | ```bash 19 | 20 | composer require felipemateus/iptv-channels 21 | 22 | ``` 23 | 24 | ### Verify this file 'config/app.php' 25 | 26 | ```php 27 | [ 30 | ... 31 | FelipeMateus\IPTVChannels\IPTVProvider::class, 32 | ... 33 | 34 | ]; 35 | 36 | ``` 37 | 38 | ### Migrate the database 39 | 40 | ```bash 41 | php artisan migrate 42 | 43 | ``` 44 | 45 | ## Extra 46 | 47 | - [more info about iptv-channels](https://felipemateus.com/blog/2021/08/pacote-gerenciador-de-canais-iptv-no-laravel) 48 | 49 | - To add new locale compatibility you need contribute to [iptv-core](https://github.com/eufelipemateus/laravel-iptv-core/blob/main/src/Helpers/Locale.php) first. 50 | 51 | - [Discord Channel to discussion about sugestion,Feature and etc.](https://discord.com/channels/885888529845076078/953528360615690270) 52 | 53 | ## License 54 | 55 | [![License](http://poser.pugx.org/felipemateus/iptv-channels/license)](https://packagist.org/packages/felipemateus/iptv-channels) 56 | 57 | ## Author 58 | 59 | [Felipe Mateus](https://felipemateus.com) 60 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "felipemateus/iptv-channels", 3 | "description": "This package controls the IPTV channel list and generates an m3u8 file using laravel.", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Felipe Mateus", 9 | "email": "eu@felipemateus.com", 10 | "homepage": "https://felipemateus.com", 11 | "role": "Developer" 12 | } 13 | ], 14 | "keywords":[ 15 | "Laravel", 16 | "IPTV", 17 | "IPTVCHannels", 18 | "Channels", 19 | "iptv-channels", 20 | "channels-m3u8", 21 | "channels-list", 22 | "iptv-laravel", 23 | "m3u8-iptv", 24 | "channel", 25 | "Playlist", 26 | "iptv-playlist", 27 | "m3u8", 28 | "laravel-package" 29 | ], 30 | "require": { 31 | "php": "^8.2", 32 | "laravel/framework": "^11", 33 | "felipemateus/iptv-core":"1.3" 34 | }, 35 | "autoload": { 36 | "psr-4": { 37 | "FelipeMateus\\IPTVChannels\\":"src/" 38 | } 39 | }, 40 | "extra": { 41 | "laravel": { 42 | "providers": [ 43 | "FelipeMateus\\IPTVChannels\\IPTVProvider" 44 | ] 45 | } 46 | }, 47 | "minimum-stability": "stable", 48 | "prefer-stable": true, 49 | "suggest": { 50 | "felipemateus/iptv-customers": "Allows you to control customers, plans assigned to each channel." 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /screenshots/channel_list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eufelipemateus/laravel-iptv-channels/76851d48d678e60f770d3a24f7940a7bc55833b8/screenshots/channel_list.jpg -------------------------------------------------------------------------------- /src/Controllers/CdnController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 22 | } 23 | 24 | /** 25 | * Show new channewl page. 26 | * 27 | * @return view -> IPTV:chanel 28 | */ 29 | public function new(){ 30 | #$data["Groupslist"] = IPTVChannelGroup::get(); 31 | return view("IPTV::cdn"); 32 | } 33 | 34 | /** 35 | * Show page from channel with id. 36 | * 37 | * @param $id - channewl id 38 | * @return view -> IPTV:chanel 39 | */ 40 | public function show($id){ 41 | $data["cdn"] = IPTVCdn::findOrFail($id); 42 | //$data["Groupslist"] = IPTVChannelGroup::get(); 43 | return view("IPTV::cdn",$data); 44 | } 45 | 46 | /** 47 | * Save new data from new channel in database. 48 | * 49 | * @return redirect -> list_channels 50 | */ 51 | public function create(Request $request){ 52 | $this->validate($request, [ 53 | 'slug' => 'required|unique:iptv_cdns', 54 | 'name' => 'required', 55 | ]); 56 | $data = $request->all(); 57 | $c = IPTVCdn::create($data); 58 | // Save Image 59 | $c->save(); 60 | return redirect()->route('list_cdn'); 61 | } 62 | 63 | /** 64 | * Save new data from new channel in database. 65 | * 66 | * @param id from channel 67 | * @return redirect -> list_channels 68 | */ 69 | public function update($id,Request $request){ 70 | $cdn = IPTVCdn::findOrFail($id); 71 | 72 | $this->validate($request, [ 73 | 'slug' => ['required',Rule::unique('iptv_cdns')->ignore($cdn->id, 'id')], 74 | 'name' => 'required', 75 | ]); 76 | 77 | $data = $request->all(); 78 | $cdn->update($data); 79 | 80 | return redirect()->route('list_cdn'); 81 | } 82 | 83 | /** 84 | * Delete channel form database. 85 | * 86 | * @param id from channel 87 | * @return redirect -> list_channel 88 | */ 89 | public function delete($id,Request $request){ 90 | $cdn =IPTVCdn::findOrFail($id); 91 | $cdn->delete(); 92 | return redirect()->route('list_cdn'); 93 | } 94 | 95 | /** 96 | * Return a channel List from database. 97 | * 98 | * @return view -> IPTV::channel_list 99 | */ 100 | public function list(){ 101 | 102 | if(class_exists(IPTVCdnCustomer::class)){ 103 | $data['list'] = IPTVCdnCustomer::all(); 104 | }else { 105 | $data['list'] = IPTVCdn::all(); 106 | } 107 | 108 | $data['url_cdn'] = IPTVConfig::get('URL_CDN'); 109 | $data['donwload'] = IPTVConfig::get('DOWNLOAD_FILE'); 110 | return view("IPTV::cdn_list",$data); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Controllers/ChannelController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 24 | } 25 | 26 | /** 27 | * Show new channewl page. 28 | * 29 | * @return view -> IPTV:chanel 30 | */ 31 | public function new(){ 32 | $data["Groupslist"] = IPTVChannelGroup::get(); 33 | $data['radio_stream'] = IPTVConfig::get("RADIO_STREAM"); 34 | return view("IPTV::channel",$data); 35 | } 36 | 37 | /** 38 | * Show page from channel with id. 39 | * 40 | * @param $id - channewl id 41 | * @return view -> IPTV:chanel 42 | */ 43 | public function show($id){ 44 | $data["Channel"] = IPTVChannel::findOrFail($id); 45 | $data["Groupslist"] = IPTVChannelGroup::get(); 46 | $data['Cdnslist'] = IPTVCdn::all(); 47 | $data["urls"] = IPTVUrl::where("iptv_channel_id", $id )->get(); 48 | $data['radio_stream'] = IPTVConfig::get("RADIO_STREAM"); 49 | return view("IPTV::channel",$data); 50 | } 51 | 52 | /** 53 | * Save new data from new channel in database. 54 | * 55 | * @return redirect -> list_channels 56 | */ 57 | public function create(Request $request){ 58 | $this->validate($request, [ 59 | 'number' => 'numeric|required|unique:iptv_channels', 60 | 'image' => 'required|image|mimes:jpeg,png,jpg|max:2048', 61 | 'group_id' => 'required|exists:iptv_channel_groups,id', 62 | ]); 63 | $data = $request->all(); 64 | $c = IPTVChannel::create($data); 65 | // Save Image 66 | $c->logo = $request->file('image') ; 67 | $c->save(); 68 | return redirect()->route('list_channel'); 69 | } 70 | 71 | /** 72 | * Save new data from new channel in database. 73 | * 74 | * @param id from channel 75 | * @return redirect -> list_channels 76 | */ 77 | public function update($id,Request $request){ 78 | $channel =IPTVChannel::findOrFail($id); 79 | 80 | $this->validate($request, [ 81 | 'number' => ['required','numeric',Rule::unique('iptv_channels')->ignore($channel->id, 'id')], 82 | 'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048', 83 | 'group_id' => 'required|exists:iptv_channel_groups,id', 84 | ]); 85 | 86 | $data = $request->all(); 87 | $channel->update($data); 88 | $image = $request->file('image'); 89 | 90 | if(isset($image)){ 91 | $channel->logo=$image; 92 | } 93 | if(!isset($data['radio'])){ 94 | $channel->radio=false; 95 | }else{ 96 | $channel->radio=true; 97 | } 98 | $channel->save(); 99 | return redirect()->route('list_channel'); 100 | } 101 | 102 | /** 103 | * Delete channel form database. 104 | * 105 | * @param id from channel 106 | * @return redirect -> list_channel 107 | */ 108 | public function delete($id,Request $request){ 109 | $group =IPTVChannel::findOrFail($id); 110 | $group->delete(); 111 | return redirect()->route('list_channel'); 112 | } 113 | 114 | /** 115 | * Return a channel List from database. 116 | * 117 | * @return view -> IPTV::channel_list 118 | */ 119 | public function list(){ 120 | $data['list'] = IPTVChannel::getList(); 121 | return view("IPTV::channel_list",$data); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Controllers/ChannelListM3UController.php: -------------------------------------------------------------------------------- 1 | view("IPTV::list_M3U",$data, 200); 22 | $response->header('Content-Type', "text/plain; charset=utf-8"); 23 | 24 | if(IPTVConfig::get('DOWNLOAD_FILE')){ 25 | $response->header('Cache-Control', 'public'); 26 | $response->header('Content-Description', 'File Transfer'); 27 | $response->header('Content-Disposition', 'attachment; filename=' . $slug . '.m3u8'); 28 | } 29 | return $response; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Controllers/GroupController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 19 | } 20 | 21 | /** 22 | * Return new page _blank. 23 | * 24 | * @return view -> IPTV::group 25 | */ 26 | public function new(){ 27 | return view("IPTV::group"); 28 | } 29 | 30 | /** 31 | * Create new channel in database. 32 | * 33 | * @return redirect -> list_group 34 | */ 35 | public function create(Request $request){ 36 | $data = $request->all(); 37 | IPTVChannelGroup::create($data); 38 | return redirect()->route('list_group'); 39 | } 40 | 41 | /** 42 | * Return a page with group from database. 43 | * 44 | * @param id -> from group 45 | * @return redirect -> list_group 46 | */ 47 | public function show($id){ 48 | $data["Group"] = IPTVChannelGroup::findOrFail($id); 49 | return view("IPTV::group",$data); 50 | } 51 | 52 | /** 53 | * Update group in database 54 | * 55 | * @param id from group 56 | * @return redirect -> list_group 57 | */ 58 | public function update($id,Request $request){ 59 | $group =IPTVChannelGroup::findOrFail($id); 60 | $group->update($request->all()); 61 | return redirect()->route('list_group'); 62 | } 63 | 64 | /** 65 | * Delete group from database 66 | * 67 | * @param id from group 68 | * @return redirect -> list_group 69 | */ 70 | public function delete($id,Request $request){ 71 | $group =IPTVChannelGroup::findOrFail($id); 72 | $group->delete(); 73 | return redirect()->route('list_group'); 74 | } 75 | 76 | /** 77 | * Return list group from database 78 | * 79 | * @param id from group 80 | * @return redirect -> list_group 81 | */ 82 | public function list(){ 83 | $data["list"] = IPTVChannelGroup::get(); 84 | return view("IPTV::group_list",$data); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/Controllers/UrlController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 22 | } 23 | 24 | /** 25 | * Save new data from new channel in database. 26 | * 27 | * @return redirect -> list_channels 28 | */ 29 | public function create( Request $request){ 30 | $this->validate($request, [ 31 | 'iptv_cdn_id'=> 'required|exists:iptv_cdns,id', 32 | 'iptv_channel_id' => 'required|exists:iptv_channels,id', 33 | 'url_stream' => 'required', 34 | ]); 35 | $data = $request->all(); 36 | $c = IPTVUrl::create($data); 37 | return redirect()->route('show_channel', ['id' => $data['iptv_channel_id']]); 38 | } 39 | 40 | /** 41 | * Save new data from new channel in database. 42 | * 43 | * @param id from channel 44 | * @return redirect -> list_channels 45 | */ 46 | public function update($id,Request $request){ 47 | $url = IPTVUrl::findOrFail($id); 48 | 49 | $this->validate($request, [ 50 | 'iptv_cdn_id'=> 'required|exists:iptv_cdns,id', 51 | 'iptv_channel_id' => 'required|exists:iptv_channels,id', 52 | 'url_stream' => 'required', 53 | ]); 54 | 55 | $data = $request->all(); 56 | $url->update($data); 57 | 58 | return redirect()->route('show_channel',['id'=>$data['iptv_channel_id']]); 59 | } 60 | 61 | /** 62 | * Delete channel form database. 63 | * 64 | * @param id from channel 65 | * @return redirect -> list_channel 66 | */ 67 | public function delete($id,Request $request){ 68 | $url =IPTVUrl::findOrFail($id); 69 | $url->delete(); 70 | return redirect()->route('show_channel',['id'=>$url->iptv_channel_id]); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/Dashs/Cdns.php: -------------------------------------------------------------------------------- 1 | registerMidleware(); 23 | $this->loadMigrationsFrom(__DIR__.'/database/migrations/'); 24 | $this->loadJSONTranslationsFrom(__DIR__.'/resources/translations'); 25 | $this->loadViewsFrom(__DIR__.'/resources/views', 'IPTV'); 26 | $this->loadRoutesFrom(__DIR__.'/routes.php'); 27 | $this->loadMenusFrom(__DIR__.'/resources/menu'); 28 | $this->registerDashboard(); 29 | } 30 | 31 | 32 | 33 | /** 34 | * Register the application services. 35 | * 36 | * @return void 37 | */ 38 | public function register() 39 | { 40 | // 41 | } 42 | 43 | /** 44 | * Register Midleware 45 | * 46 | * @return void 47 | */ 48 | private function registerMidleware(){ 49 | $router = $this->app->make(Router::class); 50 | $router->aliasMiddleware('public_cdn', PublicCdnMiddleware::class); 51 | } 52 | 53 | /** 54 | * Regoster Dashboard card 55 | * 56 | * @return void 57 | */ 58 | private function registerDashboard(){ 59 | $this->loadDashFrom(Channels::class); 60 | $this->loadDashFrom(Groups::class); 61 | $this->loadDashFrom(Cdns::class); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Middleware/PublicCdnMiddleware.php: -------------------------------------------------------------------------------- 1 | belongsToMany(IPTVChannel::class, 'iptv_urls','iptv_cdn_id', 'iptv_channel_id')->using(IPTVUrl::class); 30 | } 31 | 32 | 33 | /** 34 | * This function will return always true. 35 | */ 36 | public function canDelete(){ 37 | return true; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/Model/IPTVChannel.php: -------------------------------------------------------------------------------- 1 | belongsTo('FelipeMateus\IPTVChannels\Model\IPTVChannelGroup'); 30 | } 31 | 32 | /** 33 | * get list fucntion 34 | * 35 | * @return list 36 | */ 37 | public function scopeGetListM3u8($query, $cdn_slug){ 38 | 39 | return DB::table('iptv_cdns') 40 | ->join('iptv_urls', 'iptv_urls.iptv_cdn_id', '=', 'iptv_cdns.id') 41 | ->join('iptv_channels', 'iptv_channels.id', '=', 'iptv_urls.iptv_channel_id') 42 | ->join('iptv_channel_groups', 'iptv_channel_groups.id', '=', 'iptv_channels.group_id') 43 | ->select( 44 | 'iptv_channels.number', 45 | 'iptv_channels.name', 46 | 'iptv_channels.logo', 47 | 'iptv_channels.radio', 48 | DB::raw("iptv_channel_groups.name as group_name"), 49 | 'iptv_urls.url_stream' 50 | ) 51 | ->where('iptv_cdns.slug',$cdn_slug) 52 | ->groupBy( 53 | 'iptv_cdns.slug', 54 | 'iptv_channels.number', 55 | 'iptv_channels.name', 56 | 'iptv_channels.logo', 57 | 'iptv_channels.radio', 58 | 'iptv_channel_groups.name', 59 | 'iptv_urls.url_stream', 60 | ) 61 | ->orderBy( 62 | 'iptv_channels.number' 63 | ) 64 | ->get(); 65 | } 66 | 67 | /** 68 | * get list fucntion 69 | * 70 | * @return list 71 | */ 72 | public function scopeGetList($query){ 73 | return $query->orderBy("radio")->orderBy('number')->get(); 74 | } 75 | 76 | public function setLogoAttribute($image){ 77 | $nameLogo = md5($image->getClientOriginalName()).'.'.$image->getClientOriginalExtension(); 78 | $path = "logos/"; 79 | $destinationPath = public_path('/'.$path); 80 | $image->move($destinationPath, $nameLogo); 81 | $this->attributes['logo'] = $path.$nameLogo; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Model/IPTVChannelGroup.php: -------------------------------------------------------------------------------- 1 | hasMany('FelipeMateus\IPTVChannels\Model\IPTVChannel'); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/Model/IPTVUrl.php: -------------------------------------------------------------------------------- 1 | belongsToMany(IPTVChannel::class)->withPivot('url'); 30 | }*/ 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/database/migrations/2017_09_13_131302_create_iptv_channel_groups.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name',60); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('iptv_channel_groups'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/database/migrations/2017_09_13_133037_create_iptv_channels.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->unsignedInteger('group_id'); 19 | $table->integer("number")->unique(); 20 | $table->string("name",60); 21 | $table->text("logo",200)->nullable(); 22 | $table->boolean('radio')->default(false); 23 | $table->timestamps(); 24 | 25 | $table->foreign('group_id')->references('id')->on('iptv_channel_groups'); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('iptv_channels'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/database/migrations/2021_08_18_115119_create_iptv_cdns_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string("slug",50)->unique(); 19 | $table->string("name",90); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('iptv_cdns'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/database/migrations/2021_08_18_225941_create_iptv_urls_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->foreignId('iptv_cdn_id'); 19 | $table->foreignId('iptv_channel_id'); 20 | $table->timestamps(); 21 | 22 | $table->text('url_stream'); 23 | 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('iptv_urls'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/resources/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "title":"Channels", 4 | "menus":[ 5 | { 6 | "name":"Channels", 7 | "icon": "tv", 8 | "route": "list_channel" 9 | }, 10 | { 11 | "name":"Groups", 12 | "icon": "tv", 13 | "route": "list_group" 14 | }, 15 | { 16 | "name":"CDN", 17 | "icon": "server", 18 | "route": "list_cdn" 19 | } 20 | ] 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/resources/translations/br.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "Channel": "Canal", 4 | "Channel List": "Lista Canais", 5 | "Groups List": "Lista Grupos", 6 | "CDN List": "Lista CDN", 7 | "Add CDN": "Adicionar CDN", 8 | 9 | "Channels": "Canais", 10 | "Channels Total": "Todal de Canais", 11 | "Add Channel": "Adicionar Canal", 12 | 13 | "Groups": "Grupos", 14 | "Groups Total": "Todal de Grupos", 15 | 16 | "edit": "Editar", 17 | "delete": "Excluir", 18 | 19 | "Add Group": "Adicionar Grupo", 20 | "Channels Groups": "Grupos de Canais", 21 | "Name": "Nome", 22 | "Add Cdn": "Adicinar CDN", 23 | "Group": "Grupo", 24 | "Number": "Número", 25 | "Logo": "Logotipo", 26 | "is Radio?": "É um Rádio?", 27 | "URLs": "CDN URLs", 28 | "URl Stream": "URl Video", 29 | "Add": "Adicionar" 30 | } 31 | -------------------------------------------------------------------------------- /src/resources/translations/en.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/resources/views/cdn.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('style') 4 | 9 | @endsection 10 | 11 | @section('content') 12 | 13 |
14 |

{{ __('CDN') }}

15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
CDN
23 |
24 |
25 | 26 |
27 |
28 | 29 | {{ csrf_field() }} 30 | 31 | 32 |
33 | 34 |
35 | 36 | 37 | @if ($errors->has('slug')) 38 | 39 | {{ $errors->first('slug') }} 40 | 41 | @endif 42 |
43 |
44 | 45 |
46 | 47 |
48 | 49 |
50 |
51 | 52 |
53 |
54 | 55 |
56 |
57 | 58 |
59 |
60 |
61 |
62 |
63 |
64 | @endsection 65 | -------------------------------------------------------------------------------- /src/resources/views/cdn_dash.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ $total }} Cdns 4 |
5 | -------------------------------------------------------------------------------- /src/resources/views/cdn_list.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('content') 4 | 5 |
6 |

{{ __('CDN') }}

7 | {{ __('Add CDN')}} 9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |

CDN List

17 |
18 |
19 | 20 |
21 | @foreach($list as $cdn) 22 |
23 | 24 |
25 | {{ $cdn->slug }} 26 |
27 | 28 |
29 | {{ $cdn->name }} 30 |
31 | 32 | @if($url_cdn && !$donwload) 33 |
34 | Playslit 35 |
36 | @endif 37 | @if ($url_cdn && $donwload) 38 |
39 | Donwload 40 |
41 | @endif 42 | 43 |
44 | {{ __('edit') }} 45 |
46 | @if ($cdn->canDelete()) 47 |
48 | {{ __('delete')}} 49 |
50 | @endif 51 | 52 |
53 | @endforeach 54 | 55 | 56 |
57 |
58 |
59 |
60 |
61 | @endsection 62 | -------------------------------------------------------------------------------- /src/resources/views/channel.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('style') 4 | 32 | @endsection 33 | 34 | @section('content') 35 | 36 |
37 |

{{ __('Channels') }}

38 |
39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 |
{{ __('Channel') }}
47 |
48 |
49 | 50 |
51 |
52 | 53 | {{ csrf_field() }} 54 | 55 |
56 | 57 |
58 | 59 | 60 | @if ($errors->has('number')) 61 | 62 | {{ $errors->first('number') }} 63 | 64 | @endif 65 |
66 |
67 | 68 | 69 |
70 | 71 |
72 | logo)) required @endif placeholder="" > 73 | 74 | @if ($errors->has('image')) 75 | 76 | {{ $errors->first('image') }} 77 | 78 | @endif 79 |
80 |
81 | 82 | 83 |
84 | 85 |
86 | 87 | @if ($errors->has('name')) 88 | 89 | {{ $errors->first('name') }} 90 | 91 | @endif 92 |
93 |
94 | 95 | 96 | 97 | 98 |
99 | 100 |
101 | 106 |
107 |
108 | @if($radio_stream ) 109 |
110 |
111 | radio) checked @endif> 112 | 113 |
114 |
115 | @endif 116 |
117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 |
125 |
126 |
127 | 128 | @if(isset($Channel)) 129 |
130 |
131 |
132 |
133 |
134 |
{{ __('URLs')}}
135 |
136 |
137 |
138 | @foreach ($urls as $url) 139 |
140 | 141 | {{ csrf_field() }} 142 | 143 |
144 | 145 |
146 | 147 | 148 | @if ($errors->has('url_stream')) 149 | 150 | {{ $errors->first('url_stream') }} 151 | 152 | @endif 153 |
154 | 155 |
156 | 157 | 162 |
163 | 164 |
165 | 166 |
167 | 168 |
169 | {{ __('delete') }} 170 |
171 |
172 |
173 | @endforeach 174 |
175 | {{ csrf_field() }} 176 | 177 |
178 | 179 |
180 | 181 | 182 | @if ($errors->has('url_stream')) 183 | 184 | {{ $errors->first('url_stream') }} 185 | 186 | @endif 187 |
188 | 189 | 190 |
191 | 192 | 197 |
198 | 199 |
200 | 201 |
202 | 203 |
204 |
205 |
206 |
207 |
208 |
209 | @endif 210 |
211 | @endsection 212 | -------------------------------------------------------------------------------- /src/resources/views/channel_dash.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ $total }} channels 4 |
5 | -------------------------------------------------------------------------------- /src/resources/views/channel_list.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('content') 4 | 5 |
6 |

{{ __('Channels') }}

7 | {{ __('Add Channel') }} 9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
{{ __('Channels List') }}
17 |
18 |
19 | 20 |
21 | @foreach($list as $channel) 22 |
23 |
24 | {{ $channel->number }}. 25 |
26 |
27 | 28 |
29 |
30 | {{ $channel->name }} 31 |
32 |
33 | {{ $channel->group->name }} 34 |
35 | 36 |
37 | {{ __('edit') }} 38 |
39 |
40 | {{ __('delete')}} 41 |
42 |
43 | @endforeach 44 | 45 | 46 |
47 |
48 |
49 |
50 |
51 | @endsection 52 | -------------------------------------------------------------------------------- /src/resources/views/group.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('style') 4 | 9 | @endsection 10 | 11 | @section('content') 12 | 13 |
14 |

{{ __('Channels Groups') }}

15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
{{ __('Group') }}
23 |
24 |
25 | 26 |
27 |
28 | 29 | {{ csrf_field() }} 30 | 31 |
32 | 33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |
43 | 44 |
45 |
46 |
47 |
48 |
49 |
50 | @endsection 51 | -------------------------------------------------------------------------------- /src/resources/views/group_dash.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ $total }} Groups 4 |
5 | -------------------------------------------------------------------------------- /src/resources/views/group_list.blade.php: -------------------------------------------------------------------------------- 1 | @extends('IPTV::app') 2 | 3 | @section('content') 4 | 5 |
6 |

{{ __('Channels Groups') }}

7 | {{ __('Add Group')}} 9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
{{ __('Groups List') }}
17 |
18 |
19 | 20 |
21 | @foreach($list as $group) 22 |
23 |
24 | {{ $group->name }} 25 |
26 |
27 | {{ __('delete')}} 28 |
29 |
30 | {{ __('edit') }} 31 |
32 | 33 |
34 | @endforeach 35 |
36 |
37 |
38 |
39 |
40 | @endsection 41 | -------------------------------------------------------------------------------- /src/resources/views/list_M3U.blade.php: -------------------------------------------------------------------------------- 1 | #EXTM3U 2 | 3 | @foreach($list as $Channel) 4 | 5 | #EXTINF:-1 type="stream" @if($Channel->radio) radio=true @else tvg-id="{{$Channel->number}}" tvg-name="{{$Channel->name}}" @endif tvg-logo="{{ url($Channel->logo) }}" group-title="{{ $Channel->group_name }}",{{$Channel->name}} 6 | {{$Channel->url_stream}} 7 | @endforeach 8 | 9 | -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | 'public/m3u8', 6 | 'middleware' => ['api','public_cdn'], 7 | ], 8 | function(){ 9 | Route::get('/{slug}',"FelipeMateus\IPTVChannels\Controllers\ChannelListM3UController@show")->name("cdn-playslit"); 10 | }); 11 | Route::group([ 12 | 'middleware' => ['web', 'iptv_locale'], 13 | ], 14 | function(){ 15 | Route::prefix('channel')->group(function () { 16 | Route::get('list', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@list')->name('list_channel'); 17 | Route::get('add', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@new')->name('add_channel'); 18 | Route::post('add', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@create')->name('create_channel'); 19 | Route::get('/{id}', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@show')->name('show_channel'); 20 | Route::post('/{id}', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@update')->name('update_channel'); 21 | Route::get('/del/{id}', 'FelipeMateus\IPTVChannels\Controllers\ChannelController@delete')->name('delete_channel'); 22 | }); 23 | 24 | 25 | Route::prefix('group')->group(function () { 26 | Route::get('/list', 'FelipeMateus\IPTVChannels\Controllers\GroupController@list')->name('list_group'); 27 | 28 | Route::get('/add', 'FelipeMateus\IPTVChannels\Controllers\GroupController@new')->name('add_group'); 29 | Route::post('/add', 'FelipeMateus\IPTVChannels\Controllers\GroupController@create')->name('create_group'); 30 | 31 | Route::get('/{id}', 'FelipeMateus\IPTVChannels\Controllers\GroupController@show')->name('show_group'); 32 | 33 | Route::post('/{id}', 'FelipeMateus\IPTVChannels\Controllers\GroupController@update')->name('update_group'); 34 | Route::get('/del/{id}', 'FelipeMateus\IPTVChannels\Controllers\GroupController@delete')->name('delete_group'); 35 | }); 36 | 37 | 38 | Route::prefix('cdn')->group(function () { 39 | Route::get('/list', 'FelipeMateus\IPTVChannels\Controllers\CdnController@list')->name('list_cdn'); 40 | 41 | Route::get('/add', 'FelipeMateus\IPTVChannels\Controllers\CdnController@new')->name('add_cdn'); 42 | Route::post('/add', 'FelipeMateus\IPTVChannels\Controllers\CdnController@create')->name('create_cdn'); 43 | 44 | 45 | Route::get('/{id}', 'FelipeMateus\IPTVChannels\Controllers\CdnController@show')->name('show_cdn'); 46 | Route::post('/{id}', 'FelipeMateus\IPTVChannels\Controllers\CdnController@update')->name('update_cdn'); 47 | 48 | Route::get('/del/{id}', 'FelipeMateus\IPTVChannels\Controllers\CdnController@delete')->name('delete_cdn'); 49 | }); 50 | 51 | Route::prefix('url')->group(function () { 52 | Route::post('/add', 'FelipeMateus\IPTVChannels\Controllers\UrlController@create')->name('create_url'); 53 | Route::post('/{id}', 'FelipeMateus\IPTVChannels\Controllers\UrlController@update')->name('update_update'); 54 | Route::get('/del/{id}', 'FelipeMateus\IPTVChannels\Controllers\UrlController@delete')->name('delete_url'); 55 | }); 56 | }); 57 | --------------------------------------------------------------------------------