Skip to content

Commit 509c9b8

Browse files
authored
Merge pull request #2 from TNT-Likely/release/1.1.0
feat: 手机控制tv输入功能
2 parents 672ded2 + 9824c6f commit 509c9b8

30 files changed

+1173
-32
lines changed

README.md

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,86 @@
1-
# xplayer
1+
[English | 中文](README_EN.md)
22

3-
一个开源、全平台通用的IPTV/M3U播放器
3+
# XPlayer
44

5-
## 预览效果
5+
## 功能介绍 / Features
66

7+
- IPTV 播放器,支持本地/网络播放列表,EPG 节目单,收藏与分组
8+
- 多平台支持:Android、iOS、macOS、Windows、Android TV
9+
- TV 端支持局域网遥控输入(手机自动发现 TV,远程输入文字,实时同步 TV 输入框内容)
10+
- 远程输入支持“删除”按键
11+
- 多语言界面(中/英)
12+
13+
**预览 / Preview**
714

815
![WX20250217-170655](https://github.com/user-attachments/assets/fe341b2a-66f7-42b6-b3d0-6ece3dd47203)
916
![WX20250217-170720](https://github.com/user-attachments/assets/8632dff6-dc7a-4717-99ca-a39e9efddd04)
1017
![WX20250217-171053](https://github.com/user-attachments/assets/a14b1e50-65b9-45a1-b495-ada3983b01e9)
18+
![remotecontrol](assets/remote-control.jpg)
19+
20+
---
21+
22+
## 如何使用 / How to Use
23+
24+
1. TV 端(如 Android TV、机顶盒、Windows/macOS)安装并打开 XPlayer,导入 IPTV 播放列表
25+
2. 手机端进入“远程输入”,自动发现 TV,选择后可远程输入文字(首次发送后自动实时同步)
26+
3. 支持 Android/iOS/macOS/Windows/Android TV
27+
28+
---
29+
30+
## 开发指南 / Development
31+
32+
1. 安装依赖 / Install dependencies
33+
34+
```sh
35+
flutter pub get
36+
```
37+
38+
2. 运行 / Run
39+
40+
```sh
41+
# Android
42+
dart run flutter run -d <android_device_id>
43+
# iOS
44+
dart run flutter run -d <ios_device_id>
45+
# macOS
46+
dart run flutter run -d macos
47+
# Windows
48+
dart run flutter run -d windows
49+
# Android TV 设备同 Android
50+
```
51+
52+
3. 构建发布包 / Build release
53+
54+
```sh
55+
flutter build apk # Android
56+
flutter build ios # iOS
57+
flutter build macos # macOS
58+
flutter build windows # Windows
59+
```
60+
61+
---
62+
63+
## 常见问题 / FAQ
64+
65+
### macOS 如何打开未签名的包?
66+
67+
1. 第一次打开时如遇“无法验证开发者”,请右键 XPlayer.app > 打开,或在“系统设置 > 安全性与隐私”中允许。
68+
2. 终端可用:
69+
70+
```sh
71+
sudo xattr -rd com.apple.quarantine XPlayer.app
72+
```
1173

12-
## 下载地址
74+
### 远程输入无法发现 TV?
1375

14-
[https://github.com/TNT-Likely/xplayer/releases](https://github.com/TNT-Likely/xplayer/releases)
76+
- 请确保手机和 TV 在同一局域网
77+
- 局域网路由器需支持 mDNS/Bonjour
78+
- 可尝试重启 App
1579

16-
## 开发
80+
---
1781

18-
flutter 3.27.3
82+
## 捐赠 / Donate
1983

20-
## 特别申明
84+
如果你喜欢本项目,欢迎支持开发者!
2185

22-
本项目不提供任何IPTV源,请自行获取
86+
- 加密货币 / Crypto: ![Binance](assets/binance.jpg)

README_EN.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
[中文 | Chinese](README.md)
2+
3+
# XPlayer
4+
5+
## Features
6+
7+
- IPTV player: supports local/online playlists, EPG, favorites, and grouping
8+
- Multi-platform: Android, iOS, macOS, Windows, Android TV
9+
- TV-side LAN remote input: mobile auto-discovers TV, remote text input, real-time sync to TV input field
10+
- Remote input supports "delete" key
11+
- Multi-language UI (EN/中文)
12+
13+
**Preview**
14+
15+
![WX20250217-170655](https://github.com/user-attachments/assets/fe341b2a-66f7-42b6-b3d0-6ece3dd47203)
16+
![WX20250217-170720](https://github.com/user-attachments/assets/8632dff6-dc7a-4717-99ca-a39e9efddd04)
17+
![WX20250217-171053](https://github.com/user-attachments/assets/a14b1e50-65b9-45a1-b495-ada3983b01e9)
18+
![remotecontrol](assets/remote-control.jpg)
19+
20+
---
21+
22+
## How to Use
23+
24+
1. Install and open XPlayer on your TV device (Android TV, set-top box, Windows, macOS), import your IPTV playlist
25+
2. On your phone, open "Remote Input", auto-discover TV, select and input text remotely (real-time sync after first send)
26+
3. Supports Android/iOS/macOS/Windows/Android TV
27+
28+
---
29+
30+
## Development
31+
32+
1. Install dependencies
33+
34+
```sh
35+
flutter pub get
36+
```
37+
38+
2. Run
39+
40+
```sh
41+
# Android
42+
dart run flutter run -d <android_device_id>
43+
# iOS
44+
dart run flutter run -d <ios_device_id>
45+
# macOS
46+
dart run flutter run -d macos
47+
# Windows
48+
dart run flutter run -d windows
49+
# Android TV is the same as Android
50+
```
51+
52+
3. Build release
53+
54+
```sh
55+
flutter build apk # Android
56+
flutter build ios # iOS
57+
flutter build macos # macOS
58+
flutter build windows # Windows
59+
```
60+
61+
---
62+
63+
## FAQ
64+
65+
### How to open unsigned app on macOS?
66+
67+
1. If you see "cannot verify developer" on first launch, right-click XPlayer.app > Open, or allow in System Settings > Security & Privacy.
68+
2. Or run in terminal:
69+
70+
```sh
71+
sudo xattr -rd com.apple.quarantine XPlayer.app
72+
```
73+
74+
### Remote input cannot find TV?
75+
76+
- Make sure your phone and TV are on the same LAN
77+
- Your router must support mDNS/Bonjour
78+
- Try restarting the app
79+
80+
---
81+
82+
## Donate
83+
84+
If you like this project, please consider supporting the developer!
85+
86+
- Crypto: ![Binance](assets/binance.jpg)

android/app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
22
<uses-permission android:name="android.permission.INTERNET"/>
33
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
4+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
5+
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
6+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
7+
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"/>
48
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
59
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
610
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

assets/binance.jpg

95.3 KB
Loading

assets/remote-control.jpg

364 KB
Loading

ios/Podfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
platform :ios, '12.0'
2+
platform :ios, '13.0'
33

44
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
55
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@@ -40,5 +40,9 @@ end
4040
post_install do |installer|
4141
installer.pods_project.targets.each do |target|
4242
flutter_additional_ios_build_settings(target)
43+
# Force Pods to build with iOS 13.0 minimum to satisfy bonsoir_darwin
44+
target.build_configurations.each do |config|
45+
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
46+
end
4347
end
4448
end

ios/Podfile.lock

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
PODS:
22
- auto_orientation (0.0.1):
33
- Flutter
4+
- bonsoir_darwin (0.0.1):
5+
- Flutter
6+
- FlutterMacOS
47
- device_info_plus (0.0.1):
58
- Flutter
69
- Flutter (1.0.0)
@@ -9,6 +12,8 @@ PODS:
912
- path_provider_foundation (0.0.1):
1013
- Flutter
1114
- FlutterMacOS
15+
- permission_handler_apple (9.3.0):
16+
- Flutter
1217
- shared_preferences_foundation (0.0.1):
1318
- Flutter
1419
- FlutterMacOS
@@ -25,10 +30,12 @@ PODS:
2530

2631
DEPENDENCIES:
2732
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
33+
- bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`)
2834
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
2935
- Flutter (from `Flutter`)
3036
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
3137
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
38+
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
3239
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
3340
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
3441
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@@ -38,6 +45,8 @@ DEPENDENCIES:
3845
EXTERNAL SOURCES:
3946
auto_orientation:
4047
:path: ".symlinks/plugins/auto_orientation/ios"
48+
bonsoir_darwin:
49+
:path: ".symlinks/plugins/bonsoir_darwin/darwin"
4150
device_info_plus:
4251
:path: ".symlinks/plugins/device_info_plus/ios"
4352
Flutter:
@@ -46,6 +55,8 @@ EXTERNAL SOURCES:
4655
:path: ".symlinks/plugins/package_info_plus/ios"
4756
path_provider_foundation:
4857
:path: ".symlinks/plugins/path_provider_foundation/darwin"
58+
permission_handler_apple:
59+
:path: ".symlinks/plugins/permission_handler_apple/ios"
4960
shared_preferences_foundation:
5061
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
5162
sqflite_darwin:
@@ -59,16 +70,18 @@ EXTERNAL SOURCES:
5970

6071
SPEC CHECKSUMS:
6172
auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d
73+
bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842
6274
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
6375
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
6476
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
6577
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
78+
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
6679
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
6780
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
6881
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
6982
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
7083
wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56
7184

72-
PODFILE CHECKSUM: 7be2f5f74864d463a8ad433546ed1de7e0f29aef
85+
PODFILE CHECKSUM: a8ee75deebdce30d6ae8ce2024966166cf835197
7386

7487
COCOAPODS: 1.16.2

ios/Runner.xcodeproj/project.pbxproj

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
9705A1C41CF9048500538489 /* Embed Frameworks */,
200200
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
201201
A3304F42ED4BA4CAA2C9A0E4 /* [CP] Embed Pods Frameworks */,
202+
70834EB612EDFD966B2930B6 /* [CP] Copy Pods Resources */,
202203
);
203204
buildRules = (
204205
);
@@ -308,6 +309,23 @@
308309
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
309310
showEnvVarsInLog = 0;
310311
};
312+
70834EB612EDFD966B2930B6 /* [CP] Copy Pods Resources */ = {
313+
isa = PBXShellScriptBuildPhase;
314+
buildActionMask = 2147483647;
315+
files = (
316+
);
317+
inputFileListPaths = (
318+
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
319+
);
320+
name = "[CP] Copy Pods Resources";
321+
outputFileListPaths = (
322+
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
323+
);
324+
runOnlyForDeploymentPostprocessing = 0;
325+
shellPath = /bin/sh;
326+
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
327+
showEnvVarsInLog = 0;
328+
};
311329
8DAB95BA8F75AC6E930396E3 /* [CP] Check Pods Manifest.lock */ = {
312330
isa = PBXShellScriptBuildPhase;
313331
buildActionMask = 2147483647;
@@ -453,7 +471,7 @@
453471
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
454472
GCC_WARN_UNUSED_FUNCTION = YES;
455473
GCC_WARN_UNUSED_VARIABLE = YES;
456-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
474+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
457475
MTL_ENABLE_DEBUG_INFO = NO;
458476
SDKROOT = iphoneos;
459477
SUPPORTED_PLATFORMS = iphoneos;
@@ -580,7 +598,7 @@
580598
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
581599
GCC_WARN_UNUSED_FUNCTION = YES;
582600
GCC_WARN_UNUSED_VARIABLE = YES;
583-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
601+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
584602
MTL_ENABLE_DEBUG_INFO = YES;
585603
ONLY_ACTIVE_ARCH = YES;
586604
SDKROOT = iphoneos;
@@ -629,7 +647,7 @@
629647
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
630648
GCC_WARN_UNUSED_FUNCTION = YES;
631649
GCC_WARN_UNUSED_VARIABLE = YES;
632-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
650+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
633651
MTL_ENABLE_DEBUG_INFO = NO;
634652
SDKROOT = iphoneos;
635653
SUPPORTED_PLATFORMS = iphoneos;

ios/Runner/Info.plist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
<string>$(FLUTTER_BUILD_NUMBER)</string>
2525
<key>LSRequiresIPhoneOS</key>
2626
<true/>
27+
<key>NSBonjourServices</key>
28+
<array>
29+
<string>_xplayer._tcp</string>
30+
</array>
31+
<key>NSLocalNetworkUsageDescription</key>
32+
<string>用于在同一网络内发现和连接 TV 设备以进行远程输入</string>
2733
<key>UILaunchStoryboardName</key>
2834
<string>LaunchScreen</string>
2935
<key>UIMainStoryboardFile</key>

lib/localization/app_en.arb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"@@locale": "en",
23
"appTitle": "xplayer",
34
"appDescription": "A free, open-source IPTV/M3U player",
45
"settings": "Settings",
@@ -57,5 +58,17 @@
5758
"loadingFailed": "Loading Failed",
5859
"retrying": "Retrying",
5960
"loading": "Loading",
60-
"buffering": "Buffering..."
61+
"buffering": "Buffering...",
62+
"remoteInput": "Remote Input",
63+
"selectTv": "Select TV",
64+
"send": "Send",
65+
"connectedTo": "Connected: {name}@{host}",
66+
"remoteKeys": "Remote Keys",
67+
"up": "Up",
68+
"down": "Down",
69+
"left": "Left",
70+
"right": "Right",
71+
"ok": "OK",
72+
"deleteKey": "Delete",
73+
"inputPlaceholder": "Type to send to TV"
6174
}

0 commit comments

Comments
 (0)