Implement MPV integration for audio/video playback
- Initialize libmpv with audio-only configuration - Implement play, pause, resume, stop, seek controls - Add position and duration tracking from MPV - Auto-advance to next track when current ends - Update keybindings to use actual player - Add shell.nix for development environment with libmpv - Real playback now working with Enter/Space/n/p keys
This commit is contained in:
30
src/main.rs
30
src/main.rs
@@ -46,7 +46,7 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
// Initialize player
|
||||
let _player = player::Player::new()?;
|
||||
let mut player = player::Player::new()?;
|
||||
|
||||
// Initialize app state
|
||||
let mut state = AppState::new(cache, config);
|
||||
@@ -59,7 +59,7 @@ async fn main() -> Result<()> {
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
// Run app
|
||||
let result = run_app(&mut terminal, &mut state).await;
|
||||
let result = run_app(&mut terminal, &mut state, &mut player).await;
|
||||
|
||||
// Restore terminal
|
||||
disable_raw_mode()?;
|
||||
@@ -76,14 +76,31 @@ async fn main() -> Result<()> {
|
||||
async fn run_app<B: ratatui::backend::Backend>(
|
||||
terminal: &mut Terminal<B>,
|
||||
state: &mut AppState,
|
||||
player: &mut player::Player,
|
||||
) -> Result<()> {
|
||||
loop {
|
||||
// Update position and duration from player
|
||||
state.current_position = player.get_position().unwrap_or(0.0);
|
||||
state.current_duration = player.get_duration().unwrap_or(0.0);
|
||||
|
||||
// Check if track ended and play next
|
||||
if player.is_idle() && state.player_state == PlayerState::Playing {
|
||||
if state.playlist_index + 1 < state.playlist.len() {
|
||||
state.play_next();
|
||||
if let Some(ref path) = state.current_file {
|
||||
player.play(path)?;
|
||||
}
|
||||
} else {
|
||||
state.player_state = PlayerState::Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
terminal.draw(|f| ui::render(f, state))?;
|
||||
|
||||
if event::poll(std::time::Duration::from_millis(100))? {
|
||||
if let Event::Key(key) = event::read()? {
|
||||
if key.kind == KeyEventKind::Press {
|
||||
handle_key_event(state, key.code).await?;
|
||||
handle_key_event(state, player, key.code).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +113,7 @@ async fn run_app<B: ratatui::backend::Backend>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_key_event(state: &mut AppState, key_code: KeyCode) -> Result<()> {
|
||||
async fn handle_key_event(state: &mut AppState, player: &mut player::Player, key_code: KeyCode) -> Result<()> {
|
||||
match key_code {
|
||||
KeyCode::Char('q') => {
|
||||
state.should_quit = true;
|
||||
@@ -122,28 +139,33 @@ async fn handle_key_event(state: &mut AppState, key_code: KeyCode) -> Result<()>
|
||||
KeyCode::Char('n') => {
|
||||
state.play_next();
|
||||
if let Some(ref path) = state.current_file {
|
||||
player.play(path)?;
|
||||
tracing::info!("Next track: {:?}", path);
|
||||
}
|
||||
}
|
||||
KeyCode::Char('p') => {
|
||||
state.play_previous();
|
||||
if let Some(ref path) = state.current_file {
|
||||
player.play(path)?;
|
||||
tracing::info!("Previous track: {:?}", path);
|
||||
}
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
state.play_selection();
|
||||
if let Some(ref path) = state.current_file {
|
||||
player.play(path)?;
|
||||
tracing::info!("Playing: {:?} (playlist: {} tracks)", path, state.playlist.len());
|
||||
}
|
||||
}
|
||||
KeyCode::Char(' ') => {
|
||||
match state.player_state {
|
||||
PlayerState::Playing => {
|
||||
player.pause()?;
|
||||
state.player_state = PlayerState::Paused;
|
||||
tracing::info!("Paused");
|
||||
}
|
||||
PlayerState::Paused => {
|
||||
player.resume()?;
|
||||
state.player_state = PlayerState::Playing;
|
||||
tracing::info!("Resumed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user