mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-09 17:08:58 -05:00
Generate chapter names based on segment order
Introduces a helper function to assign chapter titles like 'Chapter 1', 'Chapter 2', etc., based on the chronological position of each segment. Updates all segment creation and splitting logic in TimelineControls and useVideoChapters to use this naming convention for improved clarity and consistency.
This commit is contained in:
parent
e06115b8ee
commit
bd786c0fe6
@ -125,6 +125,17 @@ const TimelineControls = ({
|
|||||||
onPlayPause, // Add this prop
|
onPlayPause, // Add this prop
|
||||||
isPlayingSegments = false,
|
isPlayingSegments = false,
|
||||||
}: TimelineControlsProps) => {
|
}: TimelineControlsProps) => {
|
||||||
|
// Helper function to generate proper chapter name based on chronological position
|
||||||
|
const generateChapterName = (newSegmentStartTime: number, existingSegments: Segment[]): string => {
|
||||||
|
// Create a temporary array with all segments including the new one
|
||||||
|
const allSegments = [...existingSegments, { startTime: newSegmentStartTime } as Segment];
|
||||||
|
// Sort by start time to find chronological position
|
||||||
|
const sortedSegments = allSegments.sort((a, b) => a.startTime - b.startTime);
|
||||||
|
// Find the index of our new segment
|
||||||
|
const chapterIndex = sortedSegments.findIndex(seg => seg.startTime === newSegmentStartTime);
|
||||||
|
return `Chapter ${chapterIndex + 1}`;
|
||||||
|
};
|
||||||
|
|
||||||
const timelineRef = useRef<HTMLDivElement>(null);
|
const timelineRef = useRef<HTMLDivElement>(null);
|
||||||
const leftHandleRef = useRef<HTMLDivElement>(null);
|
const leftHandleRef = useRef<HTMLDivElement>(null);
|
||||||
const rightHandleRef = useRef<HTMLDivElement>(null);
|
const rightHandleRef = useRef<HTMLDivElement>(null);
|
||||||
@ -2939,10 +2950,10 @@ const TimelineControls = ({
|
|||||||
const segmentStartTime = clickedTime;
|
const segmentStartTime = clickedTime;
|
||||||
const segmentEndTime = segmentStartTime + availableSegmentDuration;
|
const segmentEndTime = segmentStartTime + availableSegmentDuration;
|
||||||
|
|
||||||
// Create the new segment with a generic name
|
// Create the new segment with proper chapter name
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: `segment`,
|
chapterTitle: generateChapterName(segmentStartTime, clipSegments),
|
||||||
startTime: segmentStartTime,
|
startTime: segmentStartTime,
|
||||||
endTime: segmentEndTime,
|
endTime: segmentEndTime,
|
||||||
};
|
};
|
||||||
@ -3253,7 +3264,7 @@ const TimelineControls = ({
|
|||||||
// We're in a gap, create a new segment from gap start to clicked time
|
// We're in a gap, create a new segment from gap start to clicked time
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(gapStart, clipSegments),
|
||||||
startTime: gapStart,
|
startTime: gapStart,
|
||||||
endTime: clickedTime,
|
endTime: clickedTime,
|
||||||
};
|
};
|
||||||
@ -3286,7 +3297,7 @@ const TimelineControls = ({
|
|||||||
// Create a new segment from start of video to clicked time
|
// Create a new segment from start of video to clicked time
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(0, clipSegments),
|
||||||
startTime: 0,
|
startTime: 0,
|
||||||
endTime: clickedTime,
|
endTime: clickedTime,
|
||||||
};
|
};
|
||||||
@ -3349,7 +3360,7 @@ const TimelineControls = ({
|
|||||||
// No segments exist; create a new segment from start to clicked time
|
// No segments exist; create a new segment from start to clicked time
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(0, clipSegments),
|
||||||
startTime: 0,
|
startTime: 0,
|
||||||
endTime: clickedTime,
|
endTime: clickedTime,
|
||||||
};
|
};
|
||||||
@ -3467,7 +3478,7 @@ const TimelineControls = ({
|
|||||||
// We're in a gap, create a new segment from clicked time to gap end
|
// We're in a gap, create a new segment from clicked time to gap end
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(clickedTime, clipSegments),
|
||||||
startTime: clickedTime,
|
startTime: clickedTime,
|
||||||
endTime: gapEnd,
|
endTime: gapEnd,
|
||||||
};
|
};
|
||||||
@ -3500,7 +3511,7 @@ const TimelineControls = ({
|
|||||||
// Create a new segment from clicked time to first segment start
|
// Create a new segment from clicked time to first segment start
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(clickedTime, clipSegments),
|
||||||
startTime: clickedTime,
|
startTime: clickedTime,
|
||||||
endTime: sortedByStart[0].startTime,
|
endTime: sortedByStart[0].startTime,
|
||||||
};
|
};
|
||||||
@ -3534,7 +3545,7 @@ const TimelineControls = ({
|
|||||||
// Create a new segment from clicked time to end of video
|
// Create a new segment from clicked time to end of video
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(clickedTime, clipSegments),
|
||||||
startTime: clickedTime,
|
startTime: clickedTime,
|
||||||
endTime: duration,
|
endTime: duration,
|
||||||
};
|
};
|
||||||
@ -3597,7 +3608,7 @@ const TimelineControls = ({
|
|||||||
// No segments exist; create a new segment from clicked time to end
|
// No segments exist; create a new segment from clicked time to end
|
||||||
const newSegment: Segment = {
|
const newSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: generateChapterName(clickedTime, clipSegments),
|
||||||
startTime: clickedTime,
|
startTime: clickedTime,
|
||||||
endTime: duration,
|
endTime: duration,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,6 +13,17 @@ interface EditorState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useVideoChapters = () => {
|
const useVideoChapters = () => {
|
||||||
|
// Helper function to generate proper chapter name based on chronological position
|
||||||
|
const generateChapterName = (newSegmentStartTime: number, existingSegments: Segment[]): string => {
|
||||||
|
// Create a temporary array with all segments including the new one
|
||||||
|
const allSegments = [...existingSegments, { startTime: newSegmentStartTime } as Segment];
|
||||||
|
// Sort by start time to find chronological position
|
||||||
|
const sortedSegments = allSegments.sort((a, b) => a.startTime - b.startTime);
|
||||||
|
// Find the index of our new segment
|
||||||
|
const chapterIndex = sortedSegments.findIndex(seg => seg.startTime === newSegmentStartTime);
|
||||||
|
return `Chapter ${chapterIndex + 1}`;
|
||||||
|
};
|
||||||
|
|
||||||
// Helper function to parse time string (HH:MM:SS.mmm) to seconds
|
// Helper function to parse time string (HH:MM:SS.mmm) to seconds
|
||||||
const parseTimeToSeconds = (timeString: string): number => {
|
const parseTimeToSeconds = (timeString: string): number => {
|
||||||
const parts = timeString.split(':');
|
const parts = timeString.split(':');
|
||||||
@ -447,16 +458,19 @@ const useVideoChapters = () => {
|
|||||||
|
|
||||||
newSegments.splice(segmentIndex, 1);
|
newSegments.splice(segmentIndex, 1);
|
||||||
|
|
||||||
|
// Remove the original segment first to get accurate positioning for new segments
|
||||||
|
const segmentsWithoutOriginal = newSegments;
|
||||||
|
|
||||||
const firstHalf: Segment = {
|
const firstHalf: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: `${segmentToSplit.chapterTitle}-A`,
|
chapterTitle: generateChapterName(segmentToSplit.startTime, segmentsWithoutOriginal),
|
||||||
startTime: segmentToSplit.startTime,
|
startTime: segmentToSplit.startTime,
|
||||||
endTime: timeToSplit,
|
endTime: timeToSplit,
|
||||||
};
|
};
|
||||||
|
|
||||||
const secondHalf: Segment = {
|
const secondHalf: Segment = {
|
||||||
id: Date.now() + 1,
|
id: Date.now() + 1,
|
||||||
chapterTitle: `${segmentToSplit.chapterTitle}-B`,
|
chapterTitle: generateChapterName(timeToSplit, [...segmentsWithoutOriginal, firstHalf]),
|
||||||
startTime: timeToSplit,
|
startTime: timeToSplit,
|
||||||
endTime: segmentToSplit.endTime,
|
endTime: segmentToSplit.endTime,
|
||||||
};
|
};
|
||||||
@ -488,7 +502,7 @@ const useVideoChapters = () => {
|
|||||||
// Create a new default segment that spans the entire video
|
// Create a new default segment that spans the entire video
|
||||||
const defaultSegment: Segment = {
|
const defaultSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: 'Chapter 1',
|
||||||
startTime: 0,
|
startTime: 0,
|
||||||
endTime: videoRef.current.duration,
|
endTime: videoRef.current.duration,
|
||||||
};
|
};
|
||||||
@ -549,7 +563,7 @@ const useVideoChapters = () => {
|
|||||||
if (startTime < endTime) {
|
if (startTime < endTime) {
|
||||||
newSegments.push({
|
newSegments.push({
|
||||||
id: Date.now() + i,
|
id: Date.now() + i,
|
||||||
chapterTitle: `Segment ${i + 1}`,
|
chapterTitle: `Chapter ${i + 1}`,
|
||||||
startTime,
|
startTime,
|
||||||
endTime,
|
endTime,
|
||||||
});
|
});
|
||||||
@ -574,7 +588,7 @@ const useVideoChapters = () => {
|
|||||||
|
|
||||||
const defaultSegment: Segment = {
|
const defaultSegment: Segment = {
|
||||||
id: Date.now(),
|
id: Date.now(),
|
||||||
chapterTitle: 'segment',
|
chapterTitle: 'Chapter 1',
|
||||||
startTime: 0,
|
startTime: 0,
|
||||||
endTime: duration,
|
endTime: duration,
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user