Remove HTML video element
This commit is contained in:
parent
0cdc728587
commit
b08165d7f1
|
@ -47,8 +47,8 @@ func getThumbnails(c echo.Context) error {
|
|||
return c.File(mediaSet.ThumbnailPath())
|
||||
}
|
||||
|
||||
// getVideo is a handler that responds with the video file for a MediaSet
|
||||
func getVideo(c echo.Context) error {
|
||||
// getAudio is a handler that responds with the audio file for a MediaSet
|
||||
func getAudio(c echo.Context) error {
|
||||
videoID := c.Param("id")
|
||||
mediaSet := media.NewMediaSet(videoID)
|
||||
if err := mediaSet.Load(); err != nil {
|
||||
|
@ -56,7 +56,7 @@ func getVideo(c echo.Context) error {
|
|||
return echo.NewHTTPError(http.StatusInternalServerError, "could not load media set")
|
||||
}
|
||||
|
||||
return c.File(mediaSet.VideoPath())
|
||||
return c.File(mediaSet.EncodedAudioPath())
|
||||
}
|
||||
|
||||
// getPeaks is a handler that returns a two-dimensional array of peaks, with
|
||||
|
|
|
@ -24,7 +24,7 @@ func Start(opts Options) error {
|
|||
|
||||
e.GET("/api/media_sets/:id", getMediaSet)
|
||||
e.GET("/api/media_sets/:id/thumbnails", getThumbnails)
|
||||
e.GET("/api/media_sets/:id/video", getVideo)
|
||||
e.GET("/api/media_sets/:id/audio", getAudio)
|
||||
e.GET("/api/media_sets/:id/peaks", getPeaks)
|
||||
|
||||
return e.Start(opts.BindAddr)
|
||||
|
|
|
@ -87,7 +87,7 @@ func (d *Downloader) Download(ctx context.Context, videoID string) (*media.Media
|
|||
}()
|
||||
go func() {
|
||||
defer close(videoResultChan)
|
||||
video, videoErr := d.downloadVideo(ctx, video, mediaSet.VideoPath(), mediaSet.ThumbnailPath())
|
||||
video, videoErr := d.downloadVideo(ctx, video, mediaSet.ThumbnailPath())
|
||||
result := videoResult{video, videoErr}
|
||||
videoResultChan <- result
|
||||
wg.Done()
|
||||
|
@ -197,7 +197,7 @@ func thumbnailGridSize(msecs int) (int, int) {
|
|||
return x, x
|
||||
}
|
||||
|
||||
func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video, outPath, thumbnailOutPath string) (*media.Video, error) {
|
||||
func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video, thumbnailOutPath string) (*media.Video, error) {
|
||||
if len(video.Formats) == 0 {
|
||||
return nil, errors.New("error selecting audio format: no format available")
|
||||
}
|
||||
|
@ -209,12 +209,6 @@ func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video,
|
|||
return nil, fmt.Errorf("error fetching video stream: %v", err)
|
||||
}
|
||||
|
||||
videoFile, err := os.Create(outPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating video file: %v", err)
|
||||
}
|
||||
|
||||
streamReader := io.TeeReader(stream, videoFile)
|
||||
durationMsecs, err := strconv.Atoi(format.ApproxDurationMs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse video duration: %s", err)
|
||||
|
@ -235,7 +229,7 @@ func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video,
|
|||
"0",
|
||||
thumbnailOutPath,
|
||||
)
|
||||
cmd.Stdin = streamReader
|
||||
cmd.Stdin = stream
|
||||
cmd.Stderr = &errOut
|
||||
|
||||
if err = cmd.Run(); err != nil {
|
||||
|
|
|
@ -56,7 +56,6 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
const [waveformPeaks, setWaveformPeaks] = useState(null);
|
||||
const [overviewPeaks, setOverviewPeaks] = useState(null);
|
||||
const hudCanvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
|
||||
// TODO: error handling
|
||||
const videoID = new URLSearchParams(window.location.search).get('video_id');
|
||||
|
@ -85,16 +84,11 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
// setup player on page load:
|
||||
useEffect(() => {
|
||||
(async function () {
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
video.addEventListener('timeupdate', () => {
|
||||
setCurrentTime(video.currentTime);
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
setCurrentTime(audio.currentTime);
|
||||
});
|
||||
})();
|
||||
});
|
||||
}, []);
|
||||
|
||||
// fetch mediaset on page load:
|
||||
useEffect(() => {
|
||||
|
@ -139,16 +133,10 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
return;
|
||||
}
|
||||
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `http://localhost:8888/api/media_sets/${videoID}/video`;
|
||||
video.src = url;
|
||||
video.muted = false;
|
||||
video.volume = 1;
|
||||
video.controls = true;
|
||||
const url = `http://localhost:8888/api/media_sets/${videoID}/audio`;
|
||||
audio.src = url;
|
||||
audio.muted = false;
|
||||
audio.volume = 1;
|
||||
}, [mediaSet]);
|
||||
|
||||
// fetch new waveform peaks when zoom settings are updated:
|
||||
|
@ -238,20 +226,11 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
};
|
||||
|
||||
const handlePlay = async () => {
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
await video.play();
|
||||
await audio.play();
|
||||
};
|
||||
|
||||
const handlePause = () => {
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
video.pause();
|
||||
audio.pause();
|
||||
};
|
||||
|
||||
const handleZoomIn = () => {
|
||||
|
@ -281,14 +260,9 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
};
|
||||
|
||||
const handleSelectionStart = (x: number) => {
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const frame = canvasXToFrame(x, mediaSet.audio.frames);
|
||||
if (video.paused) {
|
||||
video.currentTime = frame / mediaSet.audio.sampleRate;
|
||||
if (audio.paused) {
|
||||
audio.currentTime = frame / mediaSet.audio.sampleRate;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -304,18 +278,14 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
};
|
||||
setZoomSettings(settings);
|
||||
|
||||
const video = videoRef.current;
|
||||
if (video == null) {
|
||||
return;
|
||||
}
|
||||
video.currentTime = startFrame / mediaSet.audio.sampleRate;
|
||||
audio.currentTime = startFrame / mediaSet.audio.sampleRate;
|
||||
};
|
||||
|
||||
// render component:
|
||||
|
||||
const wrapperProps = {
|
||||
width: '90%',
|
||||
height: '250px',
|
||||
height: '550px',
|
||||
position: 'relative',
|
||||
margin: '0 auto',
|
||||
} as React.CSSProperties;
|
||||
|
@ -342,17 +312,11 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
zIndex: 1,
|
||||
} as React.CSSProperties;
|
||||
|
||||
const overviewStyles = { ...wrapperProps, height: '60px' };
|
||||
const overviewStyles = { ...wrapperProps, height: '120px' };
|
||||
|
||||
// TODO: why is the margin needed?
|
||||
const controlPanelStyles = { margin: '1em' } as React.CSSProperties;
|
||||
const clockTextAreaProps = { color: '#999', width: '400px' };
|
||||
const videoStyles = {
|
||||
width: '30%',
|
||||
height: 'auto',
|
||||
margin: '10px auto 0 auto',
|
||||
zIndex: 2,
|
||||
} as React.CSSProperties;
|
||||
const thumbnailStyles = {
|
||||
width: '90%',
|
||||
height: '35px',
|
||||
|
@ -362,7 +326,6 @@ export const Waveform: React.FC<Props> = ({ audioContext }: Props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<video ref={videoRef} style={videoStyles}></video>
|
||||
<Thumbnails mediaSet={mediaSet} style={thumbnailStyles} />
|
||||
<WaveformOverview
|
||||
peaks={overviewPeaks}
|
||||
|
|
Loading…
Reference in New Issue