mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-21 09:52:33 +01:00
allow selecting track when only one
this allows the user to enable ffmpeg assisted playback when audio track is not supported closes #2144
This commit is contained in:
parent
cc202b4845
commit
be5dadcc84
@ -1,5 +1,5 @@
|
||||
import { memo, useEffect, useState, useCallback, useRef, useMemo, CSSProperties, ReactEventHandler, FocusEventHandler } from 'react';
|
||||
import { FaAngleLeft, FaWindowClose } from 'react-icons/fa';
|
||||
import { FaAngleLeft, FaRegTimesCircle } from 'react-icons/fa';
|
||||
import { MdRotate90DegreesCcw } from 'react-icons/md';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
import { ThemeProvider } from 'evergreen-ui';
|
||||
@ -60,7 +60,7 @@ import {
|
||||
RefuseOverwriteError, extractSubtitleTrackToSegments,
|
||||
mapRecommendedDefaultFormat,
|
||||
} from './ffmpeg';
|
||||
import { shouldCopyStreamByDefault, getAudioStreams, getRealVideoStreams, isAudioDefinitelyNotSupported, willPlayerProperlyHandleVideo, doesPlayerSupportHevcPlayback, getSubtitleStreams, getVideoTrackForStreamIndex, getAudioTrackForStreamIndex, enableVideoTrack, enableAudioTrack } from './util/streams';
|
||||
import { shouldCopyStreamByDefault, getAudioStreams, getRealVideoStreams, isAudioDefinitelyNotSupported, willPlayerProperlyHandleVideo, doesPlayerSupportHevcPlayback, getSubtitleStreams, enableVideoTrack, enableAudioTrack, canHtml5PlayerPlayStreams } from './util/streams';
|
||||
import { exportEdlFile, readEdlFile, loadLlcProject, askForEdlImport } from './edlStore';
|
||||
import { formatYouTube, getFrameCountRaw, formatTsv } from './edlFormats';
|
||||
import {
|
||||
@ -299,13 +299,17 @@ function App() {
|
||||
|
||||
const zoomRel = useCallback((rel: number) => setZoom((z) => Math.min(Math.max(z + (rel * (1 + (z / 10))), 1), zoomMax)), []);
|
||||
const compatPlayerRequired = usingDummyVideo;
|
||||
const compatPlayerWanted = (isRotationSet || activeVideoStreamIndex != null || activeAudioStreamIndex != null) && !hideMediaSourcePlayer;
|
||||
const compatPlayerWanted = (
|
||||
isRotationSet
|
||||
// if user selected a custom video/audio stream, use compat player if the html5 player does not have any track index corresponding to the selected stream indexes
|
||||
|| ((activeVideoStreamIndex != null || activeAudioStreamIndex != null) && videoRef.current != null && !canHtml5PlayerPlayStreams(videoRef.current, activeVideoStreamIndex, activeAudioStreamIndex))
|
||||
) && !hideMediaSourcePlayer;
|
||||
const compatPlayerEnabled = (compatPlayerRequired || compatPlayerWanted) && (activeVideoStream != null || activeAudioStream != null);
|
||||
|
||||
const shouldShowPlaybackStreamSelector = videoStreams.length > 1 || audioStreams.length > 1 || (subtitleStreams.length > 0 && !compatPlayerEnabled);
|
||||
const shouldShowPlaybackStreamSelector = videoStreams.length > 0 || audioStreams.length > 0 || (subtitleStreams.length > 0 && !compatPlayerEnabled);
|
||||
|
||||
useEffect(() => {
|
||||
// Reset the user preference when the state changes to true
|
||||
// Reset the user preference when we go from not having compat player to having it
|
||||
if (compatPlayerEnabled) setHideMediaSourcePlayer(false);
|
||||
}, [compatPlayerEnabled]);
|
||||
|
||||
@ -505,17 +509,17 @@ function App() {
|
||||
}
|
||||
}, [subtitlesByStreamId, subtitleStreams, workingRef, setWorking, filePath, loadSubtitle]);
|
||||
|
||||
const onActiveVideoStreamChange = useCallback((index?: number) => {
|
||||
const onActiveVideoStreamChange = useCallback((videoStreamIndex?: number) => {
|
||||
invariant(videoRef.current);
|
||||
setHideMediaSourcePlayer(index == null || getVideoTrackForStreamIndex(videoRef.current, index) != null);
|
||||
enableVideoTrack(videoRef.current, index);
|
||||
setActiveVideoStreamIndex(index);
|
||||
setHideMediaSourcePlayer(false);
|
||||
enableVideoTrack(videoRef.current, videoStreamIndex);
|
||||
setActiveVideoStreamIndex(videoStreamIndex);
|
||||
}, [videoRef]);
|
||||
const onActiveAudioStreamChange = useCallback((index?: number) => {
|
||||
const onActiveAudioStreamChange = useCallback((audioStreamIndex?: number) => {
|
||||
invariant(videoRef.current);
|
||||
setHideMediaSourcePlayer(index == null || getAudioTrackForStreamIndex(videoRef.current, index) != null);
|
||||
enableAudioTrack(videoRef.current, index);
|
||||
setActiveAudioStreamIndex(index);
|
||||
setHideMediaSourcePlayer(false);
|
||||
enableAudioTrack(videoRef.current, audioStreamIndex);
|
||||
setActiveAudioStreamIndex(audioStreamIndex);
|
||||
}, [videoRef]);
|
||||
|
||||
const allFilesMeta = useMemo(() => ({
|
||||
@ -2421,7 +2425,9 @@ function App() {
|
||||
</>
|
||||
)}
|
||||
|
||||
{!compatPlayerRequired && <FaWindowClose role="button" style={{ cursor: 'pointer', pointerEvents: 'initial', verticalAlign: 'middle', padding: 10 }} onClick={() => setHideMediaSourcePlayer(true)} />}
|
||||
<div style={{ cursor: 'pointer', pointerEvents: 'initial', color: 'white', opacity: 0.7, padding: '.2em', marginLeft: '.5em' }} role="button" onClick={() => incrementMediaSourceQuality()} title={t('Select playback quality')}>{mediaSourceQualities[mediaSourceQuality]}</div>
|
||||
|
||||
{!compatPlayerRequired && <FaRegTimesCircle role="button" style={{ cursor: 'pointer', pointerEvents: 'initial', verticalAlign: 'middle', padding: '.2em' }} onClick={() => setHideMediaSourcePlayer(true)} />}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -2433,8 +2439,6 @@ function App() {
|
||||
<PlaybackStreamSelector subtitleStreams={subtitleStreams} videoStreams={videoStreams} audioStreams={audioStreams} activeSubtitleStreamIndex={activeSubtitleStreamIndex} activeVideoStreamIndex={activeVideoStreamIndex} activeAudioStreamIndex={activeAudioStreamIndex} onActiveSubtitleChange={onActiveSubtitleChange} onActiveVideoStreamChange={onActiveVideoStreamChange} onActiveAudioStreamChange={onActiveAudioStreamChange} />
|
||||
)}
|
||||
|
||||
{compatPlayerEnabled && <div style={{ color: 'white', opacity: 0.7, padding: '.5em' }} role="button" onClick={() => incrementMediaSourceQuality()} title={t('Select playback quality')}>{mediaSourceQualities[mediaSourceQuality]}</div>}
|
||||
|
||||
{!showRightBar && (
|
||||
<FaAngleLeft
|
||||
title={t('Show sidebar')}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { memo, useState, useCallback, useRef, useEffect } from 'react';
|
||||
import { memo, useState, useCallback, useRef, useEffect, ChangeEventHandler, ChangeEvent } from 'react';
|
||||
import { MdSubtitles } from 'react-icons/md';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Select from './Select';
|
||||
@ -36,16 +36,16 @@ function PlaybackStreamSelector({
|
||||
timeoutRef.current = window.setTimeout(() => setControlVisible(false), 7000);
|
||||
}, []);
|
||||
|
||||
const onChange = useCallback((e, fn) => {
|
||||
const onChange = useCallback((e: ChangeEvent<HTMLSelectElement>, fn: (a: number | undefined) => void) => {
|
||||
resetTimer();
|
||||
const index = e.target.value ? parseInt(e.target.value, 10) : undefined;
|
||||
fn(index);
|
||||
e.target.blur();
|
||||
}, [resetTimer]);
|
||||
|
||||
const onActiveSubtitleChange2 = useCallback((e) => onChange(e, onActiveSubtitleChange), [onActiveSubtitleChange, onChange]);
|
||||
const onActiveVideoStreamChange2 = useCallback((e) => onChange(e, onActiveVideoStreamChange), [onActiveVideoStreamChange, onChange]);
|
||||
const onActiveAudioStreamChange2 = useCallback((e) => onChange(e, onActiveAudioStreamChange), [onActiveAudioStreamChange, onChange]);
|
||||
const onActiveSubtitleChange2 = useCallback<ChangeEventHandler<HTMLSelectElement>>((e) => onChange(e, onActiveSubtitleChange), [onActiveSubtitleChange, onChange]);
|
||||
const onActiveVideoStreamChange2 = useCallback<ChangeEventHandler<HTMLSelectElement>>((e) => onChange(e, onActiveVideoStreamChange), [onActiveVideoStreamChange, onChange]);
|
||||
const onActiveAudioStreamChange2 = useCallback<ChangeEventHandler<HTMLSelectElement>>((e) => onChange(e, onActiveAudioStreamChange), [onActiveAudioStreamChange, onChange]);
|
||||
|
||||
const onIconClick = useCallback(() => {
|
||||
resetTimer();
|
||||
@ -71,7 +71,7 @@ function PlaybackStreamSelector({
|
||||
</Select>
|
||||
)}
|
||||
|
||||
{videoStreams.length > 1 && (
|
||||
{videoStreams.length > 0 && (
|
||||
<Select
|
||||
value={activeVideoStreamIndex ?? ''}
|
||||
onChange={onActiveVideoStreamChange2}
|
||||
@ -84,7 +84,7 @@ function PlaybackStreamSelector({
|
||||
</Select>
|
||||
)}
|
||||
|
||||
{audioStreams.length > 1 && (
|
||||
{audioStreams.length > 0 && (
|
||||
<Select
|
||||
value={activeAudioStreamIndex ?? ''}
|
||||
onChange={onActiveAudioStreamChange2}
|
||||
|
@ -263,8 +263,15 @@ const getHtml5TrackId = (ffmpegTrackIndex: number) => String(ffmpegTrackIndex +
|
||||
const getHtml5VideoTracks = (video: ChromiumHTMLVideoElement) => [...(video.videoTracks ?? [])];
|
||||
const getHtml5AudioTracks = (audio: ChromiumHTMLAudioElement) => [...(audio.audioTracks ?? [])];
|
||||
|
||||
export const getVideoTrackForStreamIndex = (video: ChromiumHTMLVideoElement, index) => getHtml5VideoTracks(video).find((videoTrack) => videoTrack.id === getHtml5TrackId(index));
|
||||
export const getAudioTrackForStreamIndex = (audio: ChromiumHTMLAudioElement, index) => getHtml5AudioTracks(audio).find((audioTrack) => audioTrack.id === getHtml5TrackId(index));
|
||||
const getVideoTrackForStreamIndex = (video: ChromiumHTMLVideoElement, index: number) => getHtml5VideoTracks(video).find((videoTrack) => videoTrack.id === getHtml5TrackId(index));
|
||||
const getAudioTrackForStreamIndex = (audio: ChromiumHTMLAudioElement, index: number) => getHtml5AudioTracks(audio).find((audioTrack) => audioTrack.id === getHtml5TrackId(index));
|
||||
|
||||
// although not technically correct, if video and audio index is null, assume that we can play
|
||||
// the user can select an audio/video track if they want ffmpeg assisted playback
|
||||
export const canHtml5PlayerPlayStreams = (videoEl: ChromiumHTMLVideoElement, videoIndex: number | undefined, audioIndex: number | undefined) => (
|
||||
(videoIndex == null || getVideoTrackForStreamIndex(videoEl, videoIndex) != null)
|
||||
&& (audioIndex == null || getAudioTrackForStreamIndex(videoEl, audioIndex) != null)
|
||||
);
|
||||
|
||||
function resetVideoTrack(video: ChromiumHTMLVideoElement) {
|
||||
console.log('Resetting video track');
|
||||
|
Loading…
Reference in New Issue
Block a user