-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
43 changed files
with
370 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Build Flutter Release | ||
|
||
on: | ||
push: | ||
branches: | ||
- main # Trigger on pushes to the main branch | ||
|
||
permissions: | ||
contents: write # Allow creating and managing releases | ||
|
||
jobs: | ||
build: | ||
name: Build Flutter App | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Java 17 | ||
uses: actions/setup-java@v3 | ||
with: | ||
java-version: '17' | ||
distribution: 'temurin' | ||
|
||
- name: Set up Flutter | ||
uses: subosito/flutter-action@v2 | ||
with: | ||
flutter-version: '3.27.1' # Specify the Flutter version | ||
|
||
- name: Install dependencies | ||
run: flutter pub get | ||
|
||
- name: Build APK | ||
run: flutter build apk --release | ||
|
||
- name: Create GitHub Release and Upload APK | ||
uses: ncipollo/release-action@v1 | ||
with: | ||
artifacts: build/app/outputs/flutter-apk/app-release.apk | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
tag: v1.0.0 # Replace with your desired version tag | ||
name: Release v1.0.0 | ||
body: | | ||
### What's New | ||
- Initial release of the APK. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 74 additions & 0 deletions
74
android/app/src/main/res/drawable/ic_launcher_background.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<vector | ||
android:height="108dp" | ||
android:width="108dp" | ||
android:viewportHeight="108" | ||
android:viewportWidth="108" | ||
xmlns:android="http://schemas.android.com/apk/res/android"> | ||
<path android:fillColor="#3DDC84" | ||
android:pathData="M0,0h108v108h-108z"/> | ||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89" | ||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> | ||
</vector> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
<background android:drawable="@drawable/ic_launcher_background"/> | ||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> | ||
</adaptive-icon> |
5 changes: 5 additions & 0 deletions
5
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
<background android:drawable="@drawable/ic_launcher_background"/> | ||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> | ||
</adaptive-icon> |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
// Copyright 2024. Please see the AUTHORS file for details. | ||
// All rights reserved. Use of this source code is governed | ||
// by a BSD-style license that can be found in the LICENSE file. | ||
|
||
library stores; | ||
|
||
export 'play_controller.dart'; | ||
export 'iptv_controller.dart'; | ||
export 'play_controller.dart'; | ||
export 'update_controller.dart'; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,100 @@ | ||
/* | ||
* @File : iptv_controller.dart | ||
* @Author : jade | ||
* @Date : 2024/10/10 16:03 | ||
* @Email : jadehh@1ive.com | ||
* @Software : Samples | ||
* @Desc : | ||
*/ | ||
// Copyright 2024. Please see the AUTHORS file for details. | ||
// All rights reserved. Use of this source code is governed | ||
// by a BSD-style license that can be found in the LICENSE file. | ||
|
||
import 'dart:async'; | ||
import 'dart:ffi'; | ||
|
||
import 'package:get/get.dart'; | ||
import 'package:tivi/common/index.dart'; | ||
|
||
import '../index.dart'; | ||
|
||
class IptvController extends GetxController { | ||
/// 直播源分组列表 | ||
List<IptvGroup> iptvGroupList = []; | ||
|
||
/// 直播源列表 | ||
List<Iptv> get iptvList => iptvGroupList.expand((e) => e.list).toList(); | ||
|
||
/// 当前直播源 | ||
Rx<Iptv> currentIptv = Iptv.empty.obs; | ||
|
||
|
||
|
||
/// 当前频道源 | ||
RxInt currentChannel = 0.obs; | ||
|
||
/// 显示iptv信息 | ||
RxBool iptvInfoVisible = false.obs; | ||
|
||
/// 选台频道号 | ||
RxString channelNo = ''.obs; | ||
|
||
/// 确认选台定时器 | ||
Timer? confirmChannelTimer; | ||
|
||
/// 节目单 | ||
List<Epg>? epgList; | ||
|
||
/// 获取上一个直播源 | ||
Iptv getPrevIptv([Iptv? iptv]) { | ||
final prevIdx = iptvList.indexOf(iptv ?? currentIptv.value) - 1; | ||
return prevIdx < 0 ? iptvList.last : iptvList.elementAt(prevIdx); | ||
} | ||
|
||
/// 获取下一个直播源 | ||
Iptv getNextIptv([Iptv? iptv]) { | ||
final nextIdx = iptvList.indexOf(iptv ?? currentIptv.value) + 1; | ||
return nextIdx >= iptvList.length ? iptvList.first : iptvList.elementAt(nextIdx); | ||
return nextIdx >= iptvList.length | ||
? iptvList.first | ||
: iptvList.elementAt(nextIdx); | ||
} | ||
|
||
/// 获取上一个分组直播源 | ||
Iptv getPrevGroupIptv([Iptv? iptv]) { | ||
final prevIdx = (iptv?.groupIdx ?? currentIptv.value.groupIdx) - 1; | ||
return prevIdx < 0 ? iptvGroupList.last.list.first : iptvGroupList.elementAt(prevIdx).list.first; | ||
return prevIdx < 0 | ||
? iptvGroupList.last.list.first | ||
: iptvGroupList.elementAt(prevIdx).list.first; | ||
} | ||
|
||
/// 获取下一个分组直播源 | ||
Iptv getNextGroupIptv([Iptv? iptv]) { | ||
final nextIdx = (iptv?.groupIdx ?? currentIptv.value.groupIdx) + 1; | ||
return nextIdx >= iptvGroupList.length ? iptvGroupList.first.list.first : iptvGroupList.elementAt(nextIdx).list.first; | ||
return nextIdx >= iptvGroupList.length | ||
? iptvGroupList.first.list.first | ||
: iptvGroupList.elementAt(nextIdx).list.first; | ||
} | ||
|
||
/// 刷新直播源列表 | ||
Future<void> refreshIptvList({IPTVCallBack? callBack}) async { | ||
try{ | ||
iptvGroupList = await IptvUtil.refreshAndGet(callBack); | ||
}catch(e){ | ||
rethrow ; | ||
} | ||
iptvGroupList = await IptvUtil.refreshAndGet(callBack); | ||
} | ||
|
||
/// 刷新节目单 | ||
Future<void> refreshEpgList({EpgCallBack? callBack}) async { | ||
try{ | ||
epgList = await EpgUtil.refreshAndGet(iptvList.map((e) => e.tvgName).toList()); | ||
}catch(e){ | ||
rethrow; | ||
} | ||
|
||
epgList = await EpgUtil | ||
.refreshAndGet(iptvList.map((e) => e.tvgName) | ||
.toList()); | ||
} | ||
|
||
/// 手动输入频道号 | ||
void inputChannelNo(String no) { | ||
confirmChannelTimer?.cancel(); | ||
channelNo.value = channelNo.value + no; | ||
confirmChannelTimer = Timer(Duration(seconds: 4 - channelNo.value.length), () { | ||
final channel = int.tryParse(channelNo.value) ?? 0; | ||
final iptv = iptvList.firstWhere((e) => e.channel == channel, orElse: () => currentIptv.value); | ||
currentIptv = iptv.obs; | ||
RefreshEvent.refreshVod(); | ||
channelNo = ''.obs; | ||
}); | ||
confirmChannelTimer = Timer( | ||
Duration(seconds: 4 - channelNo.value.length), | ||
() { | ||
final channel = int.tryParse(channelNo.value) ?? 0; | ||
final iptv = iptvList.firstWhere( | ||
(e) => e.channel == channel, | ||
orElse: () => currentIptv.value, | ||
); | ||
currentIptv = iptv.obs; | ||
RefreshEvent.refreshVod(); | ||
channelNo = ''.obs; | ||
}, | ||
); | ||
} | ||
|
||
// 获取节目单 | ||
({RxString current, RxString next}) getIptvProgrammes(Iptv iptv) { | ||
final now = DateTime.now().millisecondsSinceEpoch; | ||
|
||
final epg = epgList?.firstWhereOrNull((element) => element.channel == iptv.tvgName); | ||
final epg = epgList?.firstWhereOrNull((e) => e.channel == iptv.tvgName); | ||
|
||
final currentProgramme = epg?.programmes.firstWhereOrNull((element) => element.start <= now && element.stop >= now); | ||
final nextProgramme = epg?.programmes.firstWhereOrNull((element) => element.start > now); | ||
final currentProgramme = epg?.programmes | ||
.firstWhereOrNull((e) => e.start <= now && e.stop >= now); | ||
final nextProgramme = epg?.programmes | ||
.firstWhereOrNull((e) => e.start > now); | ||
|
||
return (current: currentProgramme?.title.obs ?? ''.obs, next: nextProgramme?.title.obs ?? ''.obs); | ||
return ( | ||
current: currentProgramme?.title.obs ?? ''.obs, | ||
next: nextProgramme?.title.obs ?? ''.obs, | ||
); | ||
} | ||
|
||
({RxString current, RxString next}) get currentIptvProgrammes { | ||
return getIptvProgrammes(currentIptv.value); | ||
} | ||
} | ||
({RxString current, RxString next}) get currentIptvProgrammes => | ||
getIptvProgrammes(currentIptv.value); | ||
} |
Oops, something went wrong.