暂时无法自动播放
This commit is contained in:
@@ -39,6 +39,10 @@
|
||||
"os:allow-locale",
|
||||
"fs:allow-document-read",
|
||||
"fs:allow-document-write",
|
||||
"fs:default",
|
||||
"fs:allow-read-dir",
|
||||
"fs:allow-read-file",
|
||||
"fs:allow-stat",
|
||||
"store:default",
|
||||
"core:webview:allow-create-webview",
|
||||
"core:webview:allow-create-webview-window"
|
||||
|
@@ -1 +1 @@
|
||||
{"main":{"identifier":"main","description":"Capabilities for the app window","local":true,"windows":["main","secondary"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"notification:default","os:allow-platform","os:allow-arch","os:allow-family","os:allow-version","os:allow-locale","fs:allow-document-read","fs:allow-document-write","store:default","core:webview:allow-create-webview","core:webview:allow-create-webview-window"]}}
|
||||
{"main":{"identifier":"main","description":"Capabilities for the app window","local":true,"windows":["main","secondary"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"notification:default","os:allow-platform","os:allow-arch","os:allow-family","os:allow-version","os:allow-locale","fs:allow-document-read","fs:allow-document-write","fs:default","fs:allow-read-dir","fs:allow-read-file","fs:allow-stat","store:default","core:webview:allow-create-webview","core:webview:allow-create-webview-window"]}}
|
@@ -7,11 +7,12 @@ mod commands;
|
||||
use tauri::{
|
||||
menu::{Menu, MenuItem},
|
||||
tray::TrayIconBuilder,
|
||||
Manager
|
||||
Manager,
|
||||
Emitter
|
||||
};
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use player_state::PlayerState;
|
||||
use player_state::{PlayerState, VideoInfo};
|
||||
use websocket_server::WebSocketServer;
|
||||
|
||||
pub fn run() {
|
||||
@@ -22,7 +23,7 @@ pub fn run() {
|
||||
app.manage(player_state.clone());
|
||||
|
||||
// Start WebSocket server in background using tauri's async runtime
|
||||
let ws_server = WebSocketServer::new(8080, player_state.clone());
|
||||
let ws_server = WebSocketServer::new(6666, player_state.clone());
|
||||
let app_handle = app.handle().clone();
|
||||
|
||||
// Use tauri's runtime handle to spawn the async task
|
||||
@@ -32,6 +33,93 @@ pub fn run() {
|
||||
}
|
||||
});
|
||||
|
||||
// Try to auto-load video.mp4 from common locations (cwd, public/, executable dir)
|
||||
let app_handle_load = app.handle().clone();
|
||||
let player_state_for_load = player_state.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let mut candidates: Vec<std::path::PathBuf> = Vec::new();
|
||||
if let Ok(cwd) = std::env::current_dir() {
|
||||
log::info!("🔍 Searching in current working directory: {}", cwd.display());
|
||||
candidates.push(cwd.join("video.mp4"));
|
||||
candidates.push(cwd.join("public").join("video.mp4"));
|
||||
}
|
||||
if let Ok(exe_path) = std::env::current_exe() {
|
||||
log::info!("📁 Executable path: {}", exe_path.display());
|
||||
let mut ancestor_opt = exe_path.parent();
|
||||
let mut steps = 0;
|
||||
while let Some(dir) = ancestor_opt {
|
||||
log::info!("🔍 Searching in ancestor directory: {}", dir.display());
|
||||
candidates.push(dir.join("video.mp4"));
|
||||
candidates.push(dir.join("public").join("video.mp4"));
|
||||
steps += 1;
|
||||
if steps > 6 { break; }
|
||||
ancestor_opt = dir.parent();
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("📋 Total search candidates: {}", candidates.len());
|
||||
for (i, candidate) in candidates.iter().enumerate() {
|
||||
log::info!(" {}. {}", i + 1, candidate.display());
|
||||
}
|
||||
|
||||
for candidate in candidates {
|
||||
if tokio::fs::metadata(&candidate).await.is_ok() {
|
||||
let path_string = candidate.to_string_lossy().to_string();
|
||||
log::info!("✅ Found video file: {}", path_string);
|
||||
// Update backend player state
|
||||
{
|
||||
let mut state = player_state_for_load.lock().await;
|
||||
let title = candidate.file_name().and_then(|n| n.to_str()).unwrap_or("video.mp4").to_string();
|
||||
let video_info = VideoInfo {
|
||||
path: path_string.clone(),
|
||||
title,
|
||||
duration: None,
|
||||
size: None,
|
||||
format: None,
|
||||
};
|
||||
state.load_video(video_info);
|
||||
// 默认启用循环并开始播放
|
||||
state.set_loop(true);
|
||||
state.play();
|
||||
}
|
||||
|
||||
// Notify frontend to load and play the video (use absolute path; frontend will add file:// if needed)
|
||||
let _ = app_handle_load.emit("player-command", serde_json::json!({
|
||||
"type": "loadVideo",
|
||||
"path": path_string
|
||||
}));
|
||||
let _ = app_handle_load.emit("player-command", serde_json::json!({
|
||||
"type": "setLoop",
|
||||
"enabled": true
|
||||
}));
|
||||
let _ = app_handle_load.emit("player-command", serde_json::json!({
|
||||
"type": "play"
|
||||
}));
|
||||
|
||||
// Re-emit after a short delay to ensure frontend listeners are ready in dev mode
|
||||
let app_handle_clone = app_handle_load.clone();
|
||||
let delayed_path = path_string.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(800)).await;
|
||||
let _ = app_handle_clone.emit("player-command", serde_json::json!({
|
||||
"type": "loadVideo",
|
||||
"path": delayed_path
|
||||
}));
|
||||
let _ = app_handle_clone.emit("player-command", serde_json::json!({
|
||||
"type": "setLoop",
|
||||
"enabled": true
|
||||
}));
|
||||
let _ = app_handle_clone.emit("player-command", serde_json::json!({
|
||||
"type": "play"
|
||||
}));
|
||||
});
|
||||
return; // Exit early since we found a video
|
||||
}
|
||||
}
|
||||
|
||||
log::warn!("❌ No video.mp4 file found in any search location");
|
||||
});
|
||||
|
||||
// Setup tray
|
||||
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
|
||||
let menu = Menu::with_items(app, &[&quit_i])?;
|
||||
@@ -50,7 +138,7 @@ pub fn run() {
|
||||
})
|
||||
.build(app)?;
|
||||
|
||||
log::info!("Video Player initialized, WebSocket server starting on port 8080");
|
||||
log::info!("Video Player initialized, WebSocket server starting on port 6666");
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
|
@@ -1,6 +1,11 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use env_logger::Env;
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
let env = Env::default().default_filter_or("info");
|
||||
let _ = env_logger::Builder::from_env(env)
|
||||
.format_timestamp_millis()
|
||||
.try_init();
|
||||
video_player_lib::run();
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ impl WebSocketServer {
|
||||
}
|
||||
|
||||
pub async fn start(&self, app_handle: AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let addr = format!("127.0.0.1:{}", self.port);
|
||||
let addr = format!("0.0.0.0:{}", self.port);
|
||||
let listener = TcpListener::bind(&addr).await?;
|
||||
|
||||
log::info!("WebSocket server listening on: {}", addr);
|
||||
@@ -67,6 +67,23 @@ async fn handle_connection(
|
||||
let status_update = StatusUpdate::new(state.clone());
|
||||
let message = serde_json::to_string(&status_update)?;
|
||||
ws_sender.send(Message::Text(message)).await?;
|
||||
if let Some(video) = &state.current_video {
|
||||
let load_msg = serde_json::json!({
|
||||
"type": "command",
|
||||
"data": { "type": "loadVideo", "path": video.path }
|
||||
});
|
||||
ws_sender.send(Message::Text(load_msg.to_string())).await.ok();
|
||||
let loop_msg = serde_json::json!({
|
||||
"type": "command",
|
||||
"data": { "type": "setLoop", "enabled": state.is_looping }
|
||||
});
|
||||
ws_sender.send(Message::Text(loop_msg.to_string())).await.ok();
|
||||
let play_msg = serde_json::json!({
|
||||
"type": "command",
|
||||
"data": { "type": "play" }
|
||||
});
|
||||
ws_sender.send(Message::Text(play_msg.to_string())).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
// Emit connection status to frontend
|
||||
@@ -85,6 +102,12 @@ async fn handle_connection(
|
||||
if ws_message.msg_type == "command" {
|
||||
if let Ok(command) = serde_json::from_value::<PlaybackCommand>(ws_message.data) {
|
||||
handle_playback_command(command, &player_state, &app_handle).await?;
|
||||
|
||||
// Send updated status to client after handling command
|
||||
let state = player_state.lock().await;
|
||||
let status_update = StatusUpdate::new(state.clone());
|
||||
let message = serde_json::to_string(&status_update)?;
|
||||
ws_sender.send(Message::Text(message)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user