Skip to content

Commit

Permalink
♻️ Cleanup source sorting & only load src after document loaded
Browse files Browse the repository at this point in the history
  • Loading branch information
pajowu committed Dec 10, 2023
1 parent ed407ad commit a8f051d
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 54 deletions.
4 changes: 2 additions & 2 deletions frontend/src/api/document.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fetcher, makeSwrHook } from '../api';
import { RequestDataType, fetcher, makeSwrHook } from '../api';

export const listDocuments = fetcher.path('/api/v1/documents/').method('get').create();
export const createDocument = fetcher
Expand All @@ -19,7 +19,7 @@ export const useListDocuments = makeSwrHook('listDocuments', listDocuments);
export const useGetDocument = makeSwrHook('getDocument', getDocument);
export const useGetDocumentTasks = makeSwrHook('getDocumentTasks', getDocumentTasks);

export type ApiDocument = ReturnType<typeof useGetDocument>['data'];
export type ApiDocument = RequestDataType<typeof useGetDocument>;

export const deleteDocument = fetcher
.path('/api/v1/documents/{document_id}/')
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/editor/export/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type ExportProps = {
outputNameBase: string;
editor: Editor;
onClose: () => void;
document: ApiDocument;
document?: ApiDocument;
};

export type ExportType = {
Expand Down Expand Up @@ -48,7 +48,7 @@ export function ExportModal({
}: {
onClose: () => void;
editor: Editor;
document: ApiDocument;
document?: ApiDocument;
} & Omit<ComponentProps<typeof Modal>, 'label'>) {
const [exportType, setExportType] = useState(exportTypes[0]);
const ExportBodyComponent = exportType.component;
Expand Down
16 changes: 6 additions & 10 deletions frontend/src/editor/export/transcribee.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ import { Checkbox } from '../../components/form';
import { downloadBinaryAsFile } from '../../utils/download_text_as_file';
import { ExportProps } from '.';
import { HttpReader, Uint8ArrayReader, ZipWriter, Uint8ArrayWriter } from '@zip.js/zip.js';
import { sortMediaFiles } from '../../utils/use_audio';
import { LoadingSpinnerButton, SecondaryButton } from '../../components/button';
import { splitAndSortMediaFiles } from '../player';

export function TranscribeeExportBody({ onClose, outputNameBase, editor, document }: ExportProps) {
const [loading, setLoading] = useState(false);
const [includeOriginalMediaFile, setIncludeOriginalMediaFile] = useState(false);

const bestMediaUrl = useMemo(() => {
const mappedFiles =
document?.media_files.map((media) => {
return {
src: media.url,
type: media.content_type,
};
}) || [];

return sortMediaFiles(mappedFiles)[0].src;
const { videoSources, audioSources, hasVideo } = splitAndSortMediaFiles(
document?.media_files || [],
);
const bestSource = hasVideo ? videoSources[0] : audioSources[0];
return bestSource.src;
}, [document?.media_files]);

const originalMediaUrl = useMemo(() => {
Expand Down
66 changes: 30 additions & 36 deletions frontend/src/editor/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import clsx from 'clsx';
import { IconButton } from '../components/button';
import { ImBackward2, ImPause2, ImPlay3 } from 'react-icons/im';
import { useCallback, useMemo, useEffect, useState, useRef, useContext } from 'react';
import { useGetDocument } from '../api/document';
import { ApiDocument, useGetDocument } from '../api/document';
import { CssRule } from '../utils/cssdom';
import { SEEK_TO_EVENT, SeekToEvent } from './types';
import { useEvent } from '../utils/use_event';
Expand All @@ -24,6 +24,28 @@ const SKIP_SHORTCUT_SEC = 3;

let lastTabPressTs = 0;

export function splitAndSortMediaFiles(mediaFiles: ApiDocument['media_files']) {
const videoFiles = mediaFiles.filter((media) => media.tags.includes('video'));
const audioFiles = mediaFiles.filter((media) => !media.tags.includes('video'));

const mapFile = (media: (typeof mediaFiles)[0]) => {
return {
src: media.url,
type: media.content_type,
tags: media.tags,
};
};

const mappedVideoFiles = videoFiles.map(mapFile);
const mappedAudioFiles = audioFiles.map(mapFile);

return {
videoSources: sortMediaFiles(mappedVideoFiles),
audioSources: sortMediaFiles(mappedAudioFiles),
hasVideo: videoFiles.length > 0,
};
}

export function PlayerBar({
documentId,
editor,
Expand All @@ -41,43 +63,15 @@ export function PlayerBar({
},
);

const [playbackRate, setPlaybackRate] = useLocalStorage('playbackRate', 1);

const { videoSources, audioSources, hasVideo } = useMemo(() => {
// do not play the original file, it may be large
let relevantMediaFiles =
data?.media_files.filter((media) => !media.tags.includes('original')) || [];

// but if the original is all we have, better play this than nothing at all
if (
relevantMediaFiles.length == 0 &&
data?.media_files !== undefined &&
data?.media_files.length > 0
) {
relevantMediaFiles = data.media_files;
}

const videoFiles = relevantMediaFiles.filter((media) => media.tags.includes('video'));
const audioFiles = relevantMediaFiles.filter((media) => !media.tags.includes('video'));

const mapFile = (media: (typeof relevantMediaFiles)[0]) => {
return {
src: media.url,
type: media.content_type,
};
};

const mappedVideoFiles = videoFiles.map(mapFile);
const mappedAudioFiles = audioFiles.map(mapFile);
const { videoSources, audioSources, hasVideo } = useMemo(
() => splitAndSortMediaFiles(data?.media_files || []),
[data?.media_files],
);

return {
videoSources: sortMediaFiles(mappedVideoFiles),
audioSources: sortMediaFiles(mappedAudioFiles),
hasVideo: videoFiles.length > 0,
};
}, [data?.media_files]);
const [playbackRate, setPlaybackRate] = useLocalStorage('playbackRate', 1);

const [showVideo, setShowVideo] = useState(hasVideo);
const [_showVideo, setShowVideo] = useState(true);
const showVideo = _showVideo && hasVideo;

const audio = useAudio({
playbackRate,
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/editor/transcription_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ export function TranscriptionEditor({
className={clsx('2xl:-ml-20')}
/>
</ErrorBoundary>
<PlayerBar documentId={documentId} editor={editor} onShowVideo={onShowVideo} />
{!loadingState[0] && (
<PlayerBar documentId={documentId} editor={editor} onShowVideo={onShowVideo} />
)}
</LoadingContext.Provider>
</SpeakerColorsProvider>
</Slate>
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/utils/use_audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,21 @@ const MEDIA_PRIORITY = [
'audio/mpeg',
];

export function sortMediaFiles<T extends { type: string }>(mediaFiles: T[]) {
export function sortMediaFiles<T extends { type: string; tags: string[] }>(mediaFiles: T[]) {
const sorted = [];

const relevantMediaFiles = mediaFiles.filter((media) => !media.tags.includes('original'));
const originalMediaFiles = mediaFiles.filter((media) => media.tags.includes('original'));

for (const contentType of MEDIA_PRIORITY) {
const files = mediaFiles.filter((file) => file.type == contentType);
const files = relevantMediaFiles.filter((file) => file.type == contentType);
sorted.push(...files);
}

const rest = mediaFiles.filter((file) => !MEDIA_PRIORITY.includes(file.type));
const rest = relevantMediaFiles.filter((file) => !MEDIA_PRIORITY.includes(file.type));
sorted.push(...rest);

sorted.push(...originalMediaFiles);

return sorted;
}

0 comments on commit a8f051d

Please sign in to comment.