-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
true keyframe cut #1984
base: master
Are you sure you want to change the base?
true keyframe cut #1984
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ import pMap from 'p-map'; | |
import invariant from 'tiny-invariant'; | ||
import sortBy from 'lodash/sortBy'; | ||
|
||
import { detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime } from '../ffmpeg'; | ||
import { detectSceneChanges as ffmpegDetectSceneChanges, readFrames, mapTimesToSegments, findKeyframeNearTime, getStreamFps, getDuration } from '../ffmpeg'; | ||
import { handleError, shuffleArray } from '../util'; | ||
import { errorToast } from '../swal'; | ||
import { showParametersDialog } from '../dialogs/parameters'; | ||
|
@@ -280,18 +280,49 @@ function useSegments({ filePath, workingRef, setWorking, setCutProgress, videoSt | |
if (response == null) return; | ||
setWorking({ text: i18n.t('Aligning segments to keyframes') }); | ||
const { mode, startOrEnd } = response; | ||
|
||
if (filePath == null) throw new Error(); | ||
const frameTime = 1 / (getStreamFps(videoStream) || 1000); | ||
const duration = await getDuration(filePath); | ||
|
||
await modifySelectedSegmentTimes(async (segment) => { | ||
const newSegment = { ...segment }; | ||
|
||
async function align(key) { | ||
async function align(key: string) { | ||
const time = newSegment[key]; | ||
if (filePath == null) throw new Error(); | ||
const keyframe = await findKeyframeNearTime({ filePath, streamIndex: videoStream.index, time, mode }); | ||
if (keyframe == null) throw new Error(`Cannot find any keyframe within 60 seconds of frame ${time}`); | ||
let keyframe = await findKeyframeNearTime({ filePath, streamIndex: videoStream.index, time, mode }); | ||
if (keyframe == null) { | ||
if (mode != 'consistent') { | ||
throw new Error(`Cannot find any keyframe within 60 seconds of frame ${time}`); | ||
} | ||
keyframe = duration; | ||
} | ||
newSegment[key] = keyframe; | ||
} | ||
if (startOrEnd.includes('start')) await align('start'); | ||
if (startOrEnd.includes('end')) await align('end'); | ||
if (startOrEnd.includes('start')) { | ||
if (mode == 'consistent') { | ||
newSegment.start += frameTime * 0.3; | ||
} | ||
await align('start'); | ||
if (mode == 'consistent') { | ||
newSegment.start -= frameTime * 0.7; | ||
} | ||
} | ||
if (startOrEnd.includes('end')) { | ||
await align('end'); | ||
if (mode == 'consistent' && newSegment.end != duration) { | ||
newSegment.end -= frameTime * 0.3; | ||
} | ||
} | ||
if (startOrEnd.includes('start')) { | ||
newSegment.start = Math.min(newSegment.start, newSegment.end - frameTime * 0.99); //don't know how ffmpeg interprets cuts between frames | ||
} | ||
else { | ||
newSegment.end = Math.max(newSegment.start + frameTime * 0.99, newSegment.end); | ||
} | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tip Codebase Verification There are no unit tests covering the new 'consistent' keyframe alignment mode or the
Analysis chainThe implementation of the new 'consistent' keyframe alignment mode is complex and involves several conditional checks and adjustments to segment times. Ensure thorough testing, especially edge cases where keyframes might not be found within the expected range. Would you like assistance in writing additional unit tests for this new feature? Scripts ExecutedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify the new 'consistent' mode is covered by unit tests.
# Test: Search for unit tests covering the 'consistent' mode. Expect: Tests that handle various scenarios including edge cases.
rg --type typescript $'describe.*(consistent)'
Length of output: 82 Script: #!/bin/bash
# Description: Verify the new 'consistent' mode is covered by unit tests.
# Test: Search for unit tests covering the 'consistent' mode. Expect: Tests that handle various scenarios including edge cases.
rg --type ts $'describe.*(consistent)'
Length of output: 39 Script: #!/bin/bash
# Description: Verify if there are any tests related to the `useSegments` function.
# Test: Search for test cases related to `useSegments`. Expect: Tests that might indirectly cover the 'consistent' mode.
rg --type ts 'useSegments'
Length of output: 880 Script: #!/bin/bash
# Description: Verify if there are any test files in the repository.
# Test: Search for test files in the repository. Expect: Files that might contain tests for `useSegments`.
fd --type f --extension ts --exec rg 'test|describe|it'
Length of output: 80538 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block introduces complex logic for aligning segment times based on the new 'consistent' keyframe mode. Consider breaking down this large anonymous function into smaller, named functions to improve readability and maintainability. + async function adjustSegmentTime(segment, key, mode, frameTime, duration) {
+ const time = segment[key];
+ if (filePath == null) throw new Error('File path is required to find keyframes.');
+ let keyframe = await findKeyframeNearTime({ filePath, streamIndex: videoStream.index, time, mode });
+ if (keyframe == null) {
+ if (mode != 'consistent') {
+ throw new Error(`Cannot find any keyframe within 60 seconds of frame ${time}`);
+ }
+ keyframe = duration;
+ }
+ segment[key] = keyframe;
+ return segment;
+ }
- await modifySelectedSegmentTimes(async (segment) => {
+ await modifySelectedSegmentTime(segment => adjustSegmentTime(segment, 'start', mode, frameTime, duration));
+ await modifySelectedSegmentTime(segment => adjustSegmentTime(segment, 'end', mode, frameTime, duration));
|
||
return newSegment; | ||
}); | ||
} catch (err) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling message.
The error handling at line 284 should provide more descriptive messages to help with debugging, especially since this function deals with critical segment timing adjustments.
Consider adding a more descriptive error message:
Committable suggestion