Skip to content

优化#67

Open
NangInShell wants to merge 8 commits intomainfrom
main
Open

优化#67
NangInShell wants to merge 8 commits intomainfrom
main

Conversation

@NangInShell
Copy link
Owner

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @NangInShell, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求主要关注VSET应用程序的一系列优化和功能增强。主要改进包括带有自定义窗口控件和更新布局的刷新用户界面,一个更强大的系统来管理和显示硬件信息(CPU、GPU、内存),以及引入了外部超分模型的动态加载功能。此外,预处理选项中新增了QTGMC去隔行滤镜,为用户提供了更高级的视频质量控制。底层的视频处理逻辑也已重构,以提高可维护性和清晰度。

Highlights

  • 自定义窗口控件与界面刷新: 实现了应用程序窗口的自定义最小化、最大化和关闭按钮,同时更新了窗口尺寸,并对多个页面的整体UI样式进行了改进。
  • 动态加载额外超分模型: 应用程序现在可以自动检测并列出指定目录下的.onnx超分模型,用户可以轻松添加和选择自定义模型。
  • 集中式系统信息管理: CPU、GPU和内存信息现在通过专门的Pinia存储进行管理,提高了应用程序内数据的一致性和响应性。
  • QTGMC去隔行滤镜: 引入了新的预处理滤镜QTGMC,并提供多种预设选项,增强了AI增强前的视频质量控制。
  • 重构视频元数据提取: 提取输入和输出视频元数据(例如分辨率、帧率、音频/字幕存在性)的逻辑已被模块化为独立的、可重用的函数。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant updates across the application, focusing on system information integration, UI enhancements, and refactoring of video processing logic. The application version is bumped to 4.4.1. Key changes include:

  1. System Information & Model Management: New functions getMemoryInfo() and getExtraSRModelList() were added to src/main/getSystemInfo.ts to retrieve system memory and dynamically list available extra Super Resolution (SR) models. These are exposed to the renderer via new IPC channels (GET_MEMORY_INFO, GET_EXTRA_SR_MODEL_LIST). The SystemInfoStore in the renderer now manages and fetches CPU, GPU, memory, and SR model lists, initializing them on application startup. The EnhancePage.vue component was updated to dynamically load SR extra model options based on the fetched list and includes a watch for SRMethodValue to trigger model loading.

  2. Video Processing Refactoring: The runCommand.ts file was refactored to extract video information gathering into dedicated helper functions: getInputVideoInfo() (using ffprobe) and getOutputVideoInfo() (using vspipe --info). This improves modularity and clarity in the command execution flow. The getCorePath.ts file now includes ensureVpyDir() to create a dedicated directory for VPY files, and getGenVpyPath() was updated to use this new directory.

  3. UI/UX Improvements: The main Electron window (src/main/index.ts) now uses a custom frame (frame: false) with increased default and minimum dimensions (1000x875). Custom window controls (minimize, maximize, close) are implemented via IPC in src/main/index.ts and exposed to the renderer through src/preload/index.ts. The App.vue component was updated to render a custom title bar with these controls and a new bottom bar. HomePage.vue now displays memory information and a project link, and various components (EnhancePage.vue, FilterPage.vue, OutputPage.vue) received visual updates, including wrapping sections in n-card components and adjusting spacing and styling for tabs and sliders.

  4. Filter Enhancements: A new pre-processing filter, QTGMC, was added to FilterPage.vue, allowing users to enable it and select a preset. This involved adding new state variables in FilterStore.ts and updating getVpy.ts to include the QTGMC command in the generated VPY content.

Review Comments: The review comments primarily highlight consistency issues with strict equality operators (=== vs ==) in checkSetting.ts and a potential unit discrepancy (M vs m) in getFFmpeg.ts for bitrate. One comment also seeks clarification on a v-model change from Vfi_cudagraph to Sr_cudagraph in EnhancePage.vue, suggesting it might be a correction for a previous binding error.

<span class="demonstration" style="font-size: 15px;color: black;">cuda_graph</span>
<el-switch
v-model="Vfi_cudagraph"
v-model="Sr_cudagraph"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

n-drawer-content 中,v-modelVfi_cudagraph 更改为 Sr_cudagraph。如果这是为了修正之前错误的绑定,那么这是一个积极的改动。请确认此更改的意图,以确保它正确地控制了超分(SR)的 cuda_graph 设置。

}

if (useVfi.value === true) {
if (useVfi.value == true) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

useVfi.value === true 更改为 useVfi.value == true。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 ===

Suggested change
if (useVfi.value == true) {
if (useVfi.value === true) {

if (RifeModelValue.value === 'v4_21' || RifeModelValue.value === 'v4_22' || RifeModelValue.value === 'v4_22_lite' || RifeModelValue.value === 'v4_23'
|| RifeModelValue.value === 'v4_25' || RifeModelValue.value === 'v4_25_lite' || RifeModelValue.value === 'v4_25_heavy' || RifeModelValue.value === 'v4_26'
|| RifeModelValue.value === 'v4_26_heavy') {
if (RifeEnsembleValue.value == true) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RifeEnsembleValue.value === true 更改为 RifeEnsembleValue.value == true。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 ===

Suggested change
if (RifeEnsembleValue.value == true) {
if (RifeEnsembleValue.value === true) {

Comment on lines 26 to 28
if (RifeModelValue.value == 'v4_21' || RifeModelValue.value == 'v4_22' || RifeModelValue.value == 'v4_22_lite' || RifeModelValue.value == 'v4_23'
|| RifeModelValue.value == 'v4_25' || RifeModelValue.value == 'v4_25_lite' || RifeModelValue.value == 'v4_25_heavy' || RifeModelValue.value == 'v4_26'
|| RifeModelValue.value == 'v4_26_heavy') {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RifeModelValue.value === 'v4_21' 等严格相等比较更改为 ==。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 ===

Suggested change
if (RifeModelValue.value == 'v4_21' || RifeModelValue.value == 'v4_22' || RifeModelValue.value == 'v4_22_lite' || RifeModelValue.value == 'v4_23'
|| RifeModelValue.value == 'v4_25' || RifeModelValue.value == 'v4_25_lite' || RifeModelValue.value == 'v4_25_heavy' || RifeModelValue.value == 'v4_26'
|| RifeModelValue.value == 'v4_26_heavy') {
if (RifeModelValue.value === 'v4_21' || RifeModelValue.value === 'v4_22' || RifeModelValue.value === 'v4_22_lite' || RifeModelValue.value === 'v4_23'
|| RifeModelValue.value === 'v4_25' || RifeModelValue.value === 'v4_25_lite' || RifeModelValue.value === 'v4_25_heavy' || RifeModelValue.value === 'v4_26'
|| RifeModelValue.value === 'v4_26_heavy') {

return false
}
if (RifeScaleValue.value !== 1.0) {
if (RifeScaleValue.value != 1.0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RifeScaleValue.value !== 1.0 更改为 RifeScaleValue.value != 1.0。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 !==

Suggested change
if (RifeScaleValue.value != 1.0) {
if (RifeScaleValue.value !== 1.0) {

if (RifeScaleValue.value !== 1) {
if (RifeModelValue.value !== 'v4_0' && RifeModelValue.value !== 'v4_2' && RifeModelValue.value !== 'v4_3'
&& RifeModelValue.value !== 'v4_4' && RifeModelValue.value !== 'v4_5' && RifeModelValue.value !== 'v4_6') {
if (RifeScaleValue.value != 1.0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RifeScaleValue.value != 1.0 更改为 RifeScaleValue.value !== 1.0。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 !==

Suggested change
if (RifeScaleValue.value != 1.0) {
if (RifeScaleValue.value !== 1.0) {

Comment on lines 37 to 38
if (RifeModelValue.value != 'v4_0' && RifeModelValue.value != 'v4_2' && RifeModelValue.value != 'v4_3'
&& RifeModelValue.value != 'v4_4' && RifeModelValue.value != 'v4_5' && RifeModelValue.value != 'v4_6') {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

RifeModelValue.value != 'v4_0' 等严格相等比较更改为 ==。在 JavaScript/TypeScript 中,建议使用严格相等运算符 ===!==,以避免隐式类型转换可能导致的意外行为。请考虑将其改回 ===

Suggested change
if (RifeModelValue.value != 'v4_0' && RifeModelValue.value != 'v4_2' && RifeModelValue.value != 'v4_3'
&& RifeModelValue.value != 'v4_4' && RifeModelValue.value != 'v4_5' && RifeModelValue.value != 'v4_6') {
if (RifeModelValue.value !== 'v4_0' && RifeModelValue.value !== 'v4_2' && RifeModelValue.value !== 'v4_3'
&& RifeModelValue.value !== 'v4_4' && RifeModelValue.value !== 'v4_5' && RifeModelValue.value !== 'v4_6') {

}
else {
cmd_minor += `"-b:v" "${bitValue.value}M" `
cmd_minor += `"-b:v" "${bitValue.value}m" `

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

将比特率单位从 M 更改为 m。在 FFmpeg 中,M 通常表示兆比特(Megabits),而 m 也可以表示兆比特,但 M 更为常见和明确。如果意图是兆比特,建议使用 M 以保持一致性和清晰度。如果 m 有其他特定含义,请提供说明。

Suggested change
cmd_minor += `"-b:v" "${bitValue.value}m" `
cmd_minor += `"-b:v" "${bitValue.value}M" `

@NangInShell
Copy link
Owner Author

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次 PR 进行了大量的优化和功能增强。主要包括:

  • UI/UX 优化: 引入了无边框窗口设计,并对多个页面的布局和样式进行了现代化改造,使用了卡片式设计,使界面更加美观和易用。
  • 核心功能重构: runCommand.ts 中的命令执行逻辑被重构为多个独立的辅助函数,提高了代码的模块化和可读性。
  • 新功能:
    • 新增了对可变帧率(VFR)视频的检测,并会自动跳过处理,避免音画不同步问题。
    • 在“增强”页面,外部超分模型(Extra SR Model)现在可以动态加载,用户只需将 .onnx 模型文件放入指定目录即可使用。
    • 在“滤镜”页面,新增了 QTGMC 反交错滤镜选项。
    • 在主页显示更多系统信息,如内存大小,并能智能过滤掉虚拟显卡。
  • 状态管理: 引入了 Pinia store (SystemInfoStore) 来集中管理系统信息,取代了之前在组件内直接调用 IPC 的方式,提升了状态管理的健壮性。

代码整体质量很高,重构和新功能都实现得很好。我发现了一些可以改进的小问题,主要涉及类型安全、拼写错误和 FFmpeg 参数的标准化,具体请看我的评论。

Comment on lines 46 to 56
async function getInputVideoInfo(video: string): Promise<{
hasAudio: boolean
hasSubtitle: boolean
videoStream: any
frameRateMode: string
frameCount: string
frameRate: string
resolution: string
audioText: string
subtitleText: string
}> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

为了提高代码的可读性和可维护性,建议为 ffprobemediainfo 的输出定义类型接口,而不是使用 any 类型。这可以提供更好的类型安全和自动补全支持。

例如,您可以定义以下接口:

interface FfprobeStream {
  codec_type?: 'video' | 'audio' | 'subtitle';
  nb_frames?: string;
  avg_frame_rate?: string;
  width?: number;
  height?: number;
  [key: string]: any;
}

interface MediaInfoTrack {
  '@type': 'Video' | 'Audio' | 'General' | string;
  FrameRate_Mode?: string;
  [key: string]: any;
}

然后更新 getInputVideoInfo 函数的返回类型:

async function getInputVideoInfo(video: string): Promise<{
  hasAudio: boolean
  hasSubtitle: boolean
  videoStream: FfprobeStream | undefined
  // ... 其他属性
}>

在函数实现中,您可以使用这些类型来查找流:
const videoStream = allStreams.find((s: FfprobeStream) => s.codec_type === 'video')


/* 左侧边栏 */
.left-sider {
ackground: #ffffff; /* 白色背景 */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这里有一个拼写错误。ackground 应该是 background

  background: #ffffff; /* 白色背景 */

}
else {
cmd_minor += `"-b:v" "${bitValue.value}M" `
cmd_minor += `"-b:v" "${bitValue.value}m" `

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

FFmpeg 的码率单位后缀从 M 修改为了 m。根据 FFmpeg 官方文档,M 是标准的百万(Mega)后缀(代表 1,000,000)。虽然某些版本的 FFmpeg 可能接受 m 作为别名,但这并非标准用法,可能会被误解为“毫(milli)”或导致在不同环境下行为不一致。建议使用官方文档中明确的 M 后缀,以确保兼容性和代码清晰度。

Suggested change
cmd_minor += `"-b:v" "${bitValue.value}m" `
cmd_minor += `"-b:v" "${bitValue.value}M" `

…kground color typo in App.vue; update bit rate unit in getFFmpeg.ts
@NangInShell
Copy link
Owner Author

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant updates to the application, focusing on system information integration, enhanced video processing capabilities, and UI/UX improvements. Key changes include upgrading the project to use ES module syntax, updating the application version, and refining child process management by removing a potentially problematic ffmpeg.proc.stdin.end() call. System information retrieval has been expanded to include memory details and dynamic loading of extra Super Resolution (SR) models, with new IPC channels added for these features and for window control (minimize, maximize, close). Video processing now incorporates MediaInfo.exe to detect Variable Frame Rate (VFR) videos, skipping them with a warning to prevent audio/video desynchronization issues, and separates input/output video information gathering into dedicated functions. The UI has been revamped with a custom title bar for window controls, updated window dimensions, and improved styling across various pages using n-card components for better organization. Specifically, the 'Enhance' page now dynamically loads SR models, and the 'Filter' page introduces QTGMC deinterlacing options. The 'Home' page displays more comprehensive system info, including filtered GPU lists and memory, while the 'Render' page now provides more informative error messages from CheckSetting() and uses a new 'VideoPlay' icon for the start button. Additionally, .vpy and .lwi files are now ignored in .gitignore, and the .vpy file generation logic has been updated to store these files in a dedicated directory. Review comments highlighted an inconsistency in optional chaining for window control functions and the presence of an unused stderrOut variable in runCommand.ts.

Comment on lines +37 to +39
if (mainWindow?.isMaximized()) {
mainWindow.unmaximize()
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

mainWindow.unmaximize() 的调用与 else 块中的 mainWindow?.maximize() 在可选链操作符 ?. 的使用上不一致。虽然在这里是安全的,但保持一致的风格可以提高代码的可读性和健壮性。

Suggested change
if (mainWindow?.isMaximized()) {
mainWindow.unmaximize()
}
if (mainWindow?.isMaximized()) {
mainWindow?.unmaximize()
}

Comment on lines +165 to +178
// eslint-disable-next-line unused-imports/no-unused-vars
let stderrOut = '' // 用于保存 stderr 内容

vspipeInfoProcess.stdout.on('data', (data: Buffer) => {
const str = iconv.decode(data, 'gbk')
vspipeOut += str
event.sender.send(IpcChannelOn.FFMPEG_OUTPUT, `${str}`)
})

vspipeInfoProcess.stderr.on('data', (data: Buffer) => {
const str = iconv.decode(data, 'gbk')
stderrOut += str
event.sender.send(IpcChannelOn.FFMPEG_OUTPUT, `${str}`)
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

变量 stderrOut 被赋值但从未被使用。这是一个无用的变量,建议移除以保持代码整洁。

    vspipeInfoProcess.stdout.on('data', (data: Buffer) => {
      const str = iconv.decode(data, 'gbk')
      vspipeOut += str
      event.sender.send(IpcChannelOn.FFMPEG_OUTPUT, `${str}`)
    })

    vspipeInfoProcess.stderr.on('data', (data: Buffer) => {
      const str = iconv.decode(data, 'gbk')
      event.sender.send(IpcChannelOn.FFMPEG_OUTPUT, `${str}`)
    })

…ips for better user guidance in EnhancePage.vue and FilterPage.vue; update SystemInfoStore.ts to remove unnecessary persistence
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments