Skip to content

Commit

Permalink
Merge pull request #10 from nini22P/dev
Browse files Browse the repository at this point in the history
v1.3.0
  • Loading branch information
nini22P authored Feb 4, 2025
2 parents 7254627 + 27ea8a2 commit 30cd068
Show file tree
Hide file tree
Showing 53 changed files with 2,850 additions and 1,204 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## v1.3.0

### Changelog

* Add [FVP](https://github.com/wang-bin/fvp) player backend (Experimental, with unknown bugs)
* Adding volume adjust
* Add file sort
* Add hotkeys: Volume up ( `Arrow Up` ), Volume down ( `Arrow Down` ), Volume mute ( `Ctrl + M` ), Toggle always on top ( `F10` ), Close currently media file ( `Ctrl + C` ), Exit application ( `Alt + X` )
* Improved some visual effects

### 更新日志
* 添加 [FVP](https://github.com/wang-bin/fvp) 播放器后端(实验性,有未知bug)
* 添加音量调整
* 添加文件排序
* 添加快捷键:提升音量( `Arrow Up` )、降低音量( `Arrow Down` )、静音(`Ctrl + M`)、切换窗口置顶( `F10` )、关闭当前媒体文件( `Ctrl + C` )、退出应用( `Alt + X`
* 改进了部分视觉效果


## v1.2.1

### Changelog
Expand Down
52 changes: 29 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ English | [中文](./README_CN.md)

## Features

- [x] Base on [media-kit](https://github.com/media-kit/media-kit) supports multiple video formats
- [x] Base on [Media Kit](https://github.com/media-kit/media-kit) | [FVP](https://github.com/wang-bin/fvp), supports multiple video formats
- [x] Local storage and WebDAV support
- [x] Switchable subtitle and audio track
- [x] Playback queue support for random and repeat
Expand All @@ -33,37 +33,43 @@ English | [中文](./README_CN.md)
### Keyboard Controls
| Key | Description |
|----------------------|------------------------------------------|
| `Space` | Play / Pause / Select File |
| `Enter` | Enter Full Screen / Exit Full Screen / Select File |
| `F11` | Enter Full Screen / Exit Full Screen |
| `Space` | Play / Pause / Select file |
| `Arrow Left` | Fast backward 10 seconds |
| `Arrow Right` | Fast forward 10 seconds |
| `Arrow Up` | Volume up |
| `Arrow Down` | Volume down |
| `Ctrl + Arrow Left` | Previous |
| `Ctrl + Arrow Right` | Next |
| `Ctrl + X` | Shuffle |
| `Ctrl + R` | Repeat |
| `Ctrl + V` | Video Zoom |
| `F` | Save |
| `P` | Play Queue |
| `S` | Subtitles and Audio Tracks |
| `Ctrl + O` | Open File |
| `Ctrl + L` | Open Link |
| `Ctrl + H` | Play History |
| `Ctrl + V` | Video zoom |
| `Ctrl + M` | Volume mute |
| `S` | Subtitles and audio tracks |
| `P` | Play queue |
| `F` | Storages |
| `Ctrl + O` | Open file |
| `Ctrl + L` | Open link |
| `Ctrl + C` | Close currently media file |
| `Ctrl + H` | Play history |
| `Ctrl + P` | Settings |
| `Esc` | Exit Current Menu / Go Back / Close Full Screen |
| `Enter` | Enter full screen / Exit full screen / Select file |
| `F11` | Enter full screen / Exit full screen |
| `Esc` | Exit current Menu / Go back / Exit full screen |
| `F10` | Toggle always on top |
| `Alt + X` | Exit application |

### Gesture Controls
| Gesture | Description |
|----------------------|------------------------------------------|
| Tap | Select an item or open a menu |
| Double Tap Center | Play / Pause |
| Double Tap Left Side | Fast backward 10 seconds |
| Double Tap Right Side | Fast forward 10 seconds |
| Swipe Left / Right | Adjust playback progress |
| Swipe Up / Down on Left Side | Adjust screen brightness |
| Swipe Up / Down on Right Side | Adjust device volume |
| Long Press | Start Speed Playback |
| Long Press and Swipe Left/Right | Adjust Speed Playback Speed |
| Gesture | Description |
|---------------------------------|------------------------------------------|
| Tap | Select an item or open a menu |
| Double tap center | Play / Pause |
| Double tap left side | Fast backward 10 seconds |
| Double tap right side | Fast forward 10 seconds |
| Swipe left / right | Adjust playback progress |
| Swipe up / down on left side | Adjust screen brightness |
| Swipe up / down on right side | Adjust device volume |
| Long press | Start speed playback |
| Long press and swipe left / right | Adjust speed playback speed |

## Contribution

Expand Down
16 changes: 11 additions & 5 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

## 特性

- [x] 基于 [media-kit](https://github.com/media-kit/media-kit) 可播放多种视频格式
- [x] 基于 [Media Kit](https://github.com/media-kit/media-kit) | [FVP](https://github.com/wang-bin/fvp)可播放多种视频格式
- [x] 支持本地存储、WebDAV
- [x] 可切换字幕和音轨
- [x] 播放队列支持随机和重复
Expand All @@ -34,23 +34,29 @@
| 键位 | 描述 |
|----------------------|----------------------------------------|
| `Space` | 播放 / 暂停 / 选择文件 |
| `Enter` | 进入全屏 / 退出全屏 / 选择文件 |
| `F11` | 进入全屏 / 退出全屏 |
| `Arrow Left` | 快退 10 秒 |
| `Arrow Right` | 快进 10 秒 |
| `Arrow Up` | 提升音量 |
| `Arrow Down` | 降低音量 |
| `Ctrl + Arrow Left` | 上一个 |
| `Ctrl + Arrow Right` | 下一个 |
| `Ctrl + X` | 随机 |
| `Ctrl + R` | 重复 |
| `Ctrl + V` | 视频缩放 |
| `F` | 存储 |
| `P` | 播放队列 |
| `Ctrl + M` | 静音 |
| `S` | 字幕和音轨 |
| `P` | 播放队列 |
| `F` | 存储 |
| `Ctrl + O` | 打开文件 |
| `Ctrl + L` | 打开链接 |
| `Ctrl + C` | 关闭当前媒体文件 |
| `Ctrl + H` | 播放历史 |
| `Ctrl + P` | 设置 |
| `Enter` | 进入全屏 / 退出全屏 / 选择文件 |
| `F11` | 进入全屏 / 退出全屏 |
| `Esc` | 退出当前菜单 / 返回上一级 / 关闭全屏 |
| `F10` | 切换窗口置顶 |
| `Alt + X` | 退出应用 |

### 手势操作
| 手势 | 描述 |
Expand Down
2 changes: 2 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ GeneratedPluginRegistrant.java
key.properties
**/*.keystore
**/*.jks

/app/src/main/assets/flutter_assets
43 changes: 43 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import java.io.File
import java.nio.file.Files
import java.security.MessageDigest

plugins {
id "com.android.application"
id "kotlin-android"
Expand Down Expand Up @@ -57,3 +61,42 @@ android {
flutter {
source = "../.."
}


task downloadFiles(type: Exec) {
def filesToDownload = [
[
"url": "https://github.com/notofonts/noto-cjk/raw/refs/heads/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Medium.otf",
"md5": "58c83279d990b2cf88d40a0a34832e31",
"destination": file("./src/main/assets/flutter_assets/assets/fonts/NotoSansCJKsc-Medium.otf")
]
]

filesToDownload.each { fileInfo ->
def destFile = fileInfo.destination

if (destFile.exists()) {
def calculatedMD5 = MessageDigest.getInstance("MD5").digest(Files.readAllBytes(destFile.toPath())).encodeHex().toString()

if (calculatedMD5 != fileInfo.md5) {
destFile.delete()
println "MD5 mismatch. File deleted: ${destFile}"
}
}

if (!destFile.exists()) {
destFile.parentFile.mkdirs()
println "Downloading file from: ${fileInfo.url}"
destFile.withOutputStream { os ->
os << new URL(fileInfo.url).openStream()
}

def calculatedMD5 = MessageDigest.getInstance("MD5").digest(Files.readAllBytes(destFile.toPath())).encodeHex().toString()
if (calculatedMD5 != fileInfo.md5) {
throw new GradleException("MD5 verification failed for ${destFile}")
}
}
}
}

assemble.dependsOn(downloadFiles)
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
Expand Down
21 changes: 21 additions & 0 deletions lib/hooks/use_app_lifecycle.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'dart:ui';

import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:iris/models/player.dart';
import 'package:iris/utils/logger.dart';

void useAppLifecycle(MediaPlayer player) {
AppLifecycleState? appLifecycleState = useAppLifecycleState();

useEffect(() {
try {
if (appLifecycleState == AppLifecycleState.paused) {
logger('App lifecycle state: paused');
player.saveProgress();
}
} catch (e) {
logger('App lifecycle state error: $e');
}
return;
}, [appLifecycleState]);
}
62 changes: 62 additions & 0 deletions lib/hooks/use_cover.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_zustand/flutter_zustand.dart';
import 'package:iris/models/file.dart';
import 'package:iris/models/storages/storage.dart';
import 'package:iris/store/use_play_queue_store.dart';
import 'package:iris/store/use_storage_store.dart';
import 'package:iris/utils/files_filter.dart';

FileItem? useCover(BuildContext context) {
final playQueue =
usePlayQueueStore().select(context, (state) => state.playQueue);
final currentIndex =
usePlayQueueStore().select(context, (state) => state.currentIndex);

final int currentPlayIndex = useMemoized(
() => playQueue.indexWhere((element) => element.index == currentIndex),
[playQueue, currentIndex]);

final PlayQueueItem? currentPlay = useMemoized(
() => playQueue.isEmpty || currentPlayIndex < 0
? null
: playQueue[currentPlayIndex],
[playQueue, currentPlayIndex]);

final localStorages =
useStorageStore().select(context, (state) => state.localStorages);
final storages = useStorageStore().select(context, (state) => state.storages);

final List<String> dir = useMemoized(
() => currentPlay?.file == null || currentPlay!.file.path.isEmpty
? []
: ([...currentPlay.file.path]..removeLast()),
[currentPlay?.file],
);

final Storage? storage = useMemoized(
() => currentPlay?.file == null
? null
: [...localStorages, ...storages].firstWhereOrNull(
(storage) => storage.id == currentPlay?.file.storageId),
[currentPlay?.file, localStorages, storages]);

final getCover = useMemoized(() async {
if (currentPlay?.file.type != ContentType.audio) return null;

final files = await storage?.getFiles(dir);

if (files == null) return null;

final images = filesFilter(files, [ContentType.image]);

return images.firstWhereOrNull(
(image) => image.name.split('.').first.toLowerCase() == 'cover') ??
images.firstOrNull;
}, [currentPlay?.file, dir]);

final cover = useFuture(getCover).data;

return cover;
}
Loading

0 comments on commit 30cd068

Please sign in to comment.