feat: 增加mac/win端打包

This commit is contained in:
李岩岩 2026-02-04 18:02:52 +08:00
parent 3785fa9925
commit 989ca20d13
16 changed files with 4607 additions and 0 deletions

54
build-mac.sh Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
# IPTV Mac 构建脚本
echo "🚀 开始构建 IPTV Mac 桌面应用..."
# 检查 Rust
if ! command -v cargo &> /dev/null; then
echo "❌ Rust 未安装,请先安装:"
echo " curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
exit 1
fi
echo "✓ Rust 已安装 ($(cargo --version))"
# 步骤1: 构建 ui
echo "📦 步骤 1/4: 构建 ui 应用..."
cd ui
npm install
npm run build
cp -r public/api dist-web/
cd ..
# 步骤2: 安装 Tauri 依赖
echo "📦 步骤 2/4: 安装 Tauri..."
cd desktop
npm install
# 步骤3: 构建 Mac 应用
echo "🔨 步骤 3/4: 构建 Mac 应用(这可能需要几分钟)..."
npx tauri build
# 步骤4: 检查输出
echo "✅ 步骤 4/4: 检查输出..."
APP_PATH="src-tauri/target/release/bundle/macos/iptv-desktop.app"
DMG_PATH="src-tauri/target/release/bundle/dmg/*.dmg"
if [ -d "$APP_PATH" ]; then
echo ""
echo "🎉 构建成功!"
echo ""
echo "📱 应用位置:"
echo " $APP_PATH"
echo ""
echo "📦 安装包位置:"
ls -lh src-tauri/target/release/bundle/dmg/ 2>/dev/null || echo " DMG 未生成"
echo ""
echo "🚀 运行方式:"
echo " 1. 双击打开 $APP_PATH"
echo " 2. 或拖拽到 Applications 文件夹"
else
echo "❌ 构建失败,请检查错误信息"
exit 1
fi

84
build-windows.bat Normal file
View File

@ -0,0 +1,84 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo 🚀 开始构建 IPTV Windows 桌面应用...
echo.
:: 检查 Rust
where cargo >nul 2>nul
if %errorlevel% neq 0 (
echo ❌ Rust 未安装,请先安装:
echo 访问 https://rustup.rs/ 下载安装程序
pause
exit /b 1
)
for /f "tokens=*" %%a in ('cargo --version') do set CARGO_VERSION=%%a
echo ✓ Rust 已安装 (!CARGO_VERSION!)
echo.
:: 步骤1: 构建 ui
echo 📦 步骤 1/4: 构建 ui 应用...
cd ui
call npm install
if %errorlevel% neq 0 (
echo ❌ npm install 失败
pause
exit /b 1
)
call npm run build
if %errorlevel% neq 0 (
echo ❌ 构建 ui 失败
pause
exit /b 1
)
:: 复制 API 数据
if exist "dist-web\api" rmdir /s /q "dist-web\api"
xcopy /e /i /y "public\api" "dist-web\api"
cd ..
:: 步骤2: 安装依赖
echo 📦 步骤 2/4: 安装 Tauri 依赖...
cd desktop
call npm install
if %errorlevel% neq 0 (
echo ❌ npm install 失败
pause
exit /b 1
)
:: 步骤3: 构建 Windows 应用
echo 🔨 步骤 3/4: 构建 Windows 应用(这可能需要几分钟)...
call npx tauri build
if %errorlevel% neq 0 (
echo ❌ 构建失败
pause
exit /b 1
)
:: 步骤4: 检查输出
echo ✅ 步骤 4/4: 检查输出...
echo.
set "APP_PATH=src-tauri\target\release\bundle\msi"
set "EXE_PATH=src-tauri\target\release\bundle\nsis"
echo 🎉 构建成功!
echo.
echo 📦 安装包位置:
if exist "%APP_PATH%" (
dir /b "%APP_PATH%\*.msi" 2>nul && echo MSI: %APP_PATH%\*.msi
)
if exist "%EXE_PATH%" (
dir /b "%EXE_PATH%\*.exe" 2>nul && echo EXE: %EXE_PATH%\*.exe
)
echo.
echo 🚀 运行方式:
echo 1. 安装 MSI 版本(推荐)
echo 2. 或直接运行 exe 版本
echo.
pause

90
build-windows.ps1 Normal file
View File

@ -0,0 +1,90 @@
# IPTV Windows 构建脚本
Write-Host "🚀 开始构建 IPTV Windows 桌面应用..." -ForegroundColor Green
Write-Host ""
# 检查 Rust
try {
$cargoVersion = cargo --version
Write-Host "✓ Rust 已安装 ($cargoVersion)" -ForegroundColor Green
} catch {
Write-Host "❌ Rust 未安装,请先安装:" -ForegroundColor Red
Write-Host " 访问 https://rustup.rs/ 下载安装程序"
Read-Host "按 Enter 退出"
exit 1
}
Write-Host ""
# 步骤1: 构建 ui
Write-Host "📦 步骤 1/4: 构建 ui 应用..." -ForegroundColor Cyan
Set-Location ui
npm install
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ npm install 失败" -ForegroundColor Red
Read-Host "按 Enter 退出"
exit 1
}
npm run build
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ 构建 ui 失败" -ForegroundColor Red
Read-Host "按 Enter 退出"
exit 1
}
# 复制 API 数据
if (Test-Path "dist-web/api") {
Remove-Item "dist-web/api" -Recurse -Force
}
Copy-Item -Path "public/api" -Destination "dist-web/api" -Recurse -Force
Set-Location ..
# 步骤2: 安装依赖
Write-Host "📦 步骤 2/4: 安装 Tauri 依赖..." -ForegroundColor Cyan
Set-Location desktop
npm install
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ npm install 失败" -ForegroundColor Red
Read-Host "按 Enter 退出"
exit 1
}
# 步骤3: 构建
Write-Host "🔨 步骤 3/4: 构建 Windows 应用(这可能需要几分钟)..." -ForegroundColor Cyan
npx tauri build
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ 构建失败" -ForegroundColor Red
Read-Host "按 Enter 退出"
exit 1
}
# 步骤4: 检查输出
Write-Host "✅ 步骤 4/4: 检查输出..." -ForegroundColor Green
Write-Host ""
$msiPath = "src-tauri/target/release/bundle/msi"
$nsisPath = "src-tauri/target/release/bundle/nsis"
Write-Host "🎉 构建成功!" -ForegroundColor Green
Write-Host ""
Write-Host "📦 安装包位置:" -ForegroundColor Yellow
if (Test-Path $msiPath) {
Get-ChildItem "$msiPath/*.msi" | ForEach-Object {
Write-Host " MSI: $($_.FullName)" -ForegroundColor Gray
}
}
if (Test-Path $nsisPath) {
Get-ChildItem "$nsisPath/*.exe" | ForEach-Object {
Write-Host " EXE: $($_.FullName)" -ForegroundColor Gray
}
}
Write-Host ""
Write-Host "🚀 运行方式:" -ForegroundColor Green
Write-Host " 1. 安装 MSI 版本(推荐,有自动更新)"
Write-Host " 2. 或直接运行 EXE 版本(便携版)"
Write-Host ""
Read-Host "按 Enter 退出"

225
desktop/BUILD.md Normal file
View File

@ -0,0 +1,225 @@
# IPTV Desktop 构建指南
支持平台:**macOS** | **Windows** | **Linux**
---
## macOS 构建
### 1. 安装依赖
```bash
# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
```
### 2. 构建应用
```bash
# 一键构建
cd /Users/liyanyan/study/single-portal/iptv-app
./build-mac.sh
```
或手动构建:
```bash
cd web && npm run build && cp -r public/api dist-web/ && cd ..
cd desktop && npm install && npx tauri build
```
### 3. 输出位置
```
src-tauri/target/release/bundle/macos/IPTV Player.app
```
---
## Windows 构建
### 1. 安装依赖
1. 安装 Rust访问 https://rustup.rs/ 下载安装程序
2. 安装 Node.js访问 https://nodejs.org/ 下载 LTS 版本
### 2. 构建应用
**方式一PowerShell推荐**
```powershell
# 右键开始菜单 -> Windows PowerShell
cd C:\Users\YourName\study\single-portal\iptv-app
.\build-windows.ps1
```
**方式二CMD**
```cmd
cd C:\Users\YourName\study\single-portal\iptv-app
build-windows.bat
```
**方式三:手动**
```cmd
cd web
npm install
npm run build
xcopy /e /i /y public\api dist-web\api
cd ..\desktop
npm install
npx tauri build
```
### 3. 输出位置
```
src-tauri\target\release\bundle\msi\IPTV Player_1.0.0_x64.msi (安装版)
src-tauri\target\release\bundle\nsis\IPTV Player_1.0.0_x64.exe (便携版)
```
### 4. 安装方式
- **MSI 版**:双击安装,支持自动更新
- **EXE 版**:免安装,直接运行
---
## Linux 构建
### 1. 安装依赖
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev libssl-dev libgtk-3-dev
# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
```
### 2. 构建应用
```bash
cd /Users/liyanyan/study/single-portal/iptv-app
./build-mac.sh # 脚本通用
```
### 3. 输出位置
```
src-tauri/target/release/bundle/deb/*.deb
src-tauri/target/release/bundle/appimage/*.AppImage
```
---
## 项目结构
```
desktop/
├── package.json # Node 配置
├── BUILD.md # 本文件
├── dist-web/ # Web 静态文件
│ ├── index.html
│ └── api/ # IPTV 数据
└── src-tauri/
├── Cargo.toml # Rust 依赖
├── tauri.conf.json # Tauri 配置
├── build.rs # 构建脚本
├── src/main.rs # 入口
└── icons/ # 应用图标
```
---
## 配置说明
### tauri.conf.json 关键配置
```json
{
"windows": [{
"width": 1200,
"height": 800,
"minWidth": 900,
"minHeight": 600,
"center": true,
"title": "IPTV Player"
}]
}
```
### 自定义图标
替换 `src-tauri/icons/` 下的文件:
- `icon.icns` - Mac 图标
- `icon.ico` - Windows 图标
- `32x32.png`, `128x128.png` - Linux 图标
---
## 常见问题
### 1. Rust 未安装
```bash
# macOS/Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows
# 访问 https://rustup.rs/ 下载安装程序
```
### 2. 构建失败 "No such file or directory"
确保在项目根目录执行脚本:
```bash
cd /Users/liyanyan/study/single-portal/iptv-app
ls -la # 应该能看到 web/, desktop/, build-mac.sh
```
### 3. Windows 安装后无法运行
- 安装 WebView2 运行时Windows 10/11 通常已预装)
- 检查是否被杀毒软件拦截,添加信任
- 右键 -> 属性 -> 解除锁定(如有)
### 4. 签名问题
**Mac 开发版**
```bash
xattr -cr "IPTV Player.app" # 移除隔离属性
```
**Windows 发布版**
需要购买代码签名证书,或使用自签名(测试用)
---
## 平台特性对比
| 特性 | macOS | Windows | Linux |
|------|-------|---------|-------|
| 安装包 | .app / .dmg | .msi / .exe | .deb / .AppImage |
| 包体积 | ~5MB | ~5MB | ~5MB |
| 自动更新 | ✅ | ✅ | ✅ |
| 原生菜单 | ✅ | ✅ | ✅ |
| 系统托盘 | ✅ | ✅ | ✅ |
---
## 调试模式
开发时可以使用调试模式,更快启动:
```bash
cd desktop
npm run tauri dev
```
这会启动开发服务器,支持热重载。

39
desktop/create-icons.sh Executable file
View File

@ -0,0 +1,39 @@
#!/bin/bash
# 创建简单的默认图标
ICONS_DIR="src-tauri/icons"
# 使用ImageMagick创建简单图标如果可用
if command -v convert &> /dev/null; then
convert -size 512x512 xc: '#1a1a1a' "$ICONS_DIR/icon.png"
convert "$ICONS_DIR/icon.png" -resize 32x32 "$ICONS_DIR/32x32.png"
convert "$ICONS_DIR/icon.png" -resize 128x128 "$ICONS_DIR/128x128.png"
convert "$ICONS_DIR/icon.png" -resize 256x256 "$ICONS_DIR/128x128@2x.png"
cp "$ICONS_DIR/icon.png" "$ICONS_DIR/icon.ico"
# 添加文字
convert -size 512x512 xc: '#00d4ff' -pointsize 200 -fill white -gravity center -annotate +0+0 "IPTV" "$ICONS_DIR/icon.png"
convert "$ICONS_DIR/icon.png" "$ICONS_DIR/icon.ico"
# Mac icns
if command -v iconutil &> /dev/null; then
mkdir -p "$ICONS_DIR/icon.iconset"
for size in 16 32 64 128 256 512; do
convert "$ICONS_DIR/icon.png" -resize ${size}x${size} "$ICONS_DIR/icon.iconset/icon_${size}x${size}.png"
convert "$ICONS_DIR/icon.png" -resize $((size*2))x$((size*2)) "$ICONS_DIR/icon.iconset/icon_${size}x${size}@2x.png"
done
iconutil -c icns "$ICONS_DIR/icon.iconset" -o "$ICONS_DIR/icon.icns"
rm -rf "$ICONS_DIR/icon.iconset"
else
cp "$ICONS_DIR/icon.png" "$ICONS_DIR/icon.icns"
fi
else
# 没有ImageMagick创建空白文件作为占位
touch "$ICONS_DIR/32x32.png"
touch "$ICONS_DIR/128x128.png"
touch "$ICONS_DIR/128x128@2x.png"
touch "$ICONS_DIR/icon.icns"
touch "$ICONS_DIR/icon.ico"
echo "警告: 未找到 ImageMagick使用了空白图标文件"
fi
echo "图标创建完成"

13
desktop/package.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "iptv-desktop",
"version": "1.0.0",
"description": "IPTV Player for Mac",
"scripts": {
"tauri": "tauri",
"dev": "tauri dev",
"build": "tauri build"
},
"devDependencies": {
"@tauri-apps/cli": "^1.6.3"
}
}

4000
desktop/src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
[package]
name = "iptv-desktop"
version = "1.0.0"
description = "IPTV Player"
authors = ["ghr"]
license = "MIT"
repository = ""
edition = "2021"
[build-dependencies]
tauri-build = { version = "1.5.0", features = [] }
[dependencies]
tauri = { version = "1.5.0", features = ["shell-open"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[features]
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]

View File

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

View File

View File

View File

View File

View File

@ -0,0 +1,8 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -0,0 +1,71 @@
{
"build": {
"beforeBuildCommand": "",
"beforeDevCommand": "",
"devPath": "../dist-web",
"distDir": "../dist-web",
"withGlobalTauri": false
},
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
}
},
"bundle": {
"active": true,
"category": "Entertainment",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.iptv.player",
"longDescription": "IPTV Player for desktop",
"macOS": {
"entitlements": null,
"exceptionDomain": "",
"frameworks": [],
"providerShortName": null,
"signingIdentity": null
},
"resources": [],
"shortDescription": "IPTV Player",
"targets": "all",
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 800,
"resizable": true,
"title": "IPTV Player",
"width": 1200,
"minWidth": 900,
"minHeight": 600,
"center": true,
"decorations": true,
"transparent": false
}
]
}
}