Re-enable audio playback
This commit is contained in:
parent
b3bc63621a
commit
642ce6e349
|
@ -3,16 +3,19 @@ import {
|
||||||
GrpcWebImpl,
|
GrpcWebImpl,
|
||||||
MediaSetServiceClientImpl,
|
MediaSetServiceClientImpl,
|
||||||
GetVideoProgress,
|
GetVideoProgress,
|
||||||
|
GetAudioProgress,
|
||||||
} from './generated/media_set';
|
} from './generated/media_set';
|
||||||
|
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { VideoPreview } from './VideoPreview';
|
import { VideoPreview } from './VideoPreview';
|
||||||
import { Overview } from './Overview';
|
import { Overview, CanvasLogicalWidth } from './Overview';
|
||||||
import { Waveform } from './Waveform';
|
import { Waveform } from './Waveform';
|
||||||
import { ControlBar } from './ControlBar';
|
import { ControlBar } from './ControlBar';
|
||||||
import { SeekBar } from './SeekBar';
|
import { SeekBar } from './SeekBar';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import { Duration } from './generated/google/protobuf/duration';
|
import { Duration } from './generated/google/protobuf/duration';
|
||||||
|
import { from, Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
// ported from backend, where should they live?
|
// ported from backend, where should they live?
|
||||||
const thumbnailWidth = 177;
|
const thumbnailWidth = 177;
|
||||||
|
@ -36,8 +39,12 @@ export interface VideoPosition {
|
||||||
function App(): JSX.Element {
|
function App(): JSX.Element {
|
||||||
const [mediaSet, setMediaSet] = useState<MediaSet | null>(null);
|
const [mediaSet, setMediaSet] = useState<MediaSet | null>(null);
|
||||||
const [video, _setVideo] = useState(document.createElement('video'));
|
const [video, _setVideo] = useState(document.createElement('video'));
|
||||||
|
const [audio, _setAudio] = useState(document.createElement('audio'));
|
||||||
const [position, setPosition] = useState({ currentTime: 0, percent: 0 });
|
const [position, setPosition] = useState({ currentTime: 0, percent: 0 });
|
||||||
const [viewport, setViewport] = useState({ start: 0, end: 0 });
|
const [viewport, setViewport] = useState({ start: 0, end: 0 });
|
||||||
|
const [overviewPeaks, setOverviewPeaks] = useState<Observable<number[]>>(
|
||||||
|
from([])
|
||||||
|
);
|
||||||
|
|
||||||
// effects
|
// effects
|
||||||
|
|
||||||
|
@ -77,6 +84,37 @@ function App(): JSX.Element {
|
||||||
}, 100);
|
}, 100);
|
||||||
}, [mediaSet]);
|
}, [mediaSet]);
|
||||||
|
|
||||||
|
// load audio when MediaSet is loaded:
|
||||||
|
useEffect(() => {
|
||||||
|
(async function () {
|
||||||
|
if (mediaSet == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('fetching audio...');
|
||||||
|
// TODO move this call to app.tsx, pass the stream in as a prop.
|
||||||
|
const service = new MediaSetServiceClientImpl(newRPC());
|
||||||
|
const audioProgressStream = service.GetAudio({
|
||||||
|
id: mediaSet.id,
|
||||||
|
numBins: CanvasLogicalWidth,
|
||||||
|
});
|
||||||
|
const peaks = audioProgressStream.pipe(map((progress) => progress.peaks));
|
||||||
|
setOverviewPeaks(peaks);
|
||||||
|
|
||||||
|
let url = '';
|
||||||
|
// TODO: probably a nicer way to do this.
|
||||||
|
await audioProgressStream.forEach((progress: GetAudioProgress) => {
|
||||||
|
if (progress.url != '') {
|
||||||
|
url = progress.url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.src = url;
|
||||||
|
audio.muted = false;
|
||||||
|
audio.volume = 1;
|
||||||
|
console.log('got audio URL', url);
|
||||||
|
})();
|
||||||
|
}, [mediaSet]);
|
||||||
|
|
||||||
// load video when MediaSet is loaded:
|
// load video when MediaSet is loaded:
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async function () {
|
(async function () {
|
||||||
|
@ -98,8 +136,6 @@ function App(): JSX.Element {
|
||||||
});
|
});
|
||||||
|
|
||||||
video.src = url;
|
video.src = url;
|
||||||
video.muted = false;
|
|
||||||
video.volume = 1;
|
|
||||||
console.log('set video src', video.src);
|
console.log('set video src', video.src);
|
||||||
})();
|
})();
|
||||||
}, [mediaSet]);
|
}, [mediaSet]);
|
||||||
|
@ -161,14 +197,17 @@ function App(): JSX.Element {
|
||||||
<div style={containerStyles}>
|
<div style={containerStyles}>
|
||||||
<ControlBar
|
<ControlBar
|
||||||
onPlay={() => {
|
onPlay={() => {
|
||||||
|
audio.play();
|
||||||
video.play();
|
video.play();
|
||||||
}}
|
}}
|
||||||
onPause={() => {
|
onPause={() => {
|
||||||
video.pause();
|
video.pause();
|
||||||
|
audio.pause();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Overview
|
<Overview
|
||||||
|
peaks={overviewPeaks}
|
||||||
mediaSet={mediaSet}
|
mediaSet={mediaSet}
|
||||||
offsetPixels={offsetPixels}
|
offsetPixels={offsetPixels}
|
||||||
height={80}
|
height={80}
|
||||||
|
@ -189,6 +228,7 @@ function App(): JSX.Element {
|
||||||
offsetPixels={offsetPixels}
|
offsetPixels={offsetPixels}
|
||||||
onPositionChanged={(position: number) => {
|
onPositionChanged={(position: number) => {
|
||||||
video.currentTime = position;
|
video.currentTime = position;
|
||||||
|
audio.currentTime = position;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
import { useState, useEffect, useRef, MouseEvent } from 'react';
|
import { useState, useEffect, useRef, MouseEvent } from 'react';
|
||||||
import {
|
import { MediaSet } from './generated/media_set';
|
||||||
MediaSetServiceClientImpl,
|
import { Frames, VideoPosition } from './App';
|
||||||
MediaSet,
|
|
||||||
GetAudioProgress,
|
|
||||||
} from './generated/media_set';
|
|
||||||
import { Frames, newRPC, VideoPosition } from './App';
|
|
||||||
import { WaveformCanvas } from './WaveformCanvas';
|
import { WaveformCanvas } from './WaveformCanvas';
|
||||||
import { from, Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
|
||||||
|
|
||||||
export interface Selection {
|
export interface Selection {
|
||||||
start: number;
|
start: number;
|
||||||
|
@ -15,6 +10,7 @@ export interface Selection {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
peaks: Observable<number[]>;
|
||||||
mediaSet: MediaSet;
|
mediaSet: MediaSet;
|
||||||
height: number;
|
height: number;
|
||||||
offsetPixels: number;
|
offsetPixels: number;
|
||||||
|
@ -37,12 +33,13 @@ enum HoverState {
|
||||||
OverSelection,
|
OverSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CanvasLogicalWidth = 2_000;
|
export const CanvasLogicalWidth = 2_000;
|
||||||
const CanvasLogicalHeight = 500;
|
export const CanvasLogicalHeight = 500;
|
||||||
|
|
||||||
const emptySelection = { start: 0, end: 0 };
|
const emptySelection = { start: 0, end: 0 };
|
||||||
|
|
||||||
export const Overview: React.FC<Props> = ({
|
export const Overview: React.FC<Props> = ({
|
||||||
|
peaks,
|
||||||
mediaSet,
|
mediaSet,
|
||||||
height,
|
height,
|
||||||
offsetPixels,
|
offsetPixels,
|
||||||
|
@ -50,7 +47,6 @@ export const Overview: React.FC<Props> = ({
|
||||||
onSelectionChange,
|
onSelectionChange,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const hudCanvasRef = useRef<HTMLCanvasElement>(null);
|
const hudCanvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const [peaks, setPeaks] = useState<Observable<number[]>>(from([]));
|
|
||||||
const [mode, setMode] = useState(Mode.Normal);
|
const [mode, setMode] = useState(Mode.Normal);
|
||||||
const [hoverState, setHoverState] = useState(HoverState.Normal);
|
const [hoverState, setHoverState] = useState(HoverState.Normal);
|
||||||
const [newSelection, setNewSelection] = useState({
|
const [newSelection, setNewSelection] = useState({
|
||||||
|
@ -112,23 +108,6 @@ export const Overview: React.FC<Props> = ({
|
||||||
console.error('no hud 2d context available');
|
console.error('no hud 2d context available');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('fetching audio...');
|
|
||||||
const service = new MediaSetServiceClientImpl(newRPC());
|
|
||||||
const audioProgressStream = service.GetAudio({
|
|
||||||
id: mediaSet.id,
|
|
||||||
numBins: CanvasLogicalWidth,
|
|
||||||
});
|
|
||||||
const peaks = audioProgressStream.pipe(map((progress) => progress.peaks));
|
|
||||||
setPeaks(peaks);
|
|
||||||
|
|
||||||
let url = '';
|
|
||||||
// TODO: probably a nicer way to do this.
|
|
||||||
await audioProgressStream.forEach((progress: GetAudioProgress) => {
|
|
||||||
if (progress.url != '') {
|
|
||||||
url = progress.url;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log('got audio URL', url);
|
|
||||||
})();
|
})();
|
||||||
}, [mediaSet]);
|
}, [mediaSet]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue