[System] grab "ffmpeg"

This commit is contained in:
infinite-persistence 2021-08-07 21:35:11 +08:00
parent c55179998b
commit 96ac5a8997
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
4 changed files with 108 additions and 128 deletions

View file

@ -1,16 +1,20 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClearCache } from 'redux/actions/app'; import { doClearCache } from 'redux/actions/app';
import { doSetDaemonSetting } from 'redux/actions/settings'; import { doSetDaemonSetting, doClearDaemonSetting, doFindFFmpeg } from 'redux/actions/settings';
import { selectDaemonSettings } from 'redux/selectors/settings'; import { selectDaemonSettings, selectFfmpegStatus, selectFindingFFmpeg } from 'redux/selectors/settings';
import SettingSystem from './view'; import SettingSystem from './view';
const select = (state) => ({ const select = (state) => ({
daemonSettings: selectDaemonSettings(state), daemonSettings: selectDaemonSettings(state),
ffmpegStatus: selectFfmpegStatus(state),
findingFFmpeg: selectFindingFFmpeg(state),
}); });
const perform = (dispatch) => ({ const perform = (dispatch) => ({
setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)), setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)),
clearDaemonSetting: (key) => dispatch(doClearDaemonSetting(key)),
clearCache: () => dispatch(doClearCache()), clearCache: () => dispatch(doClearCache()),
findFFmpeg: () => dispatch(doFindFFmpeg()),
}); });
export default connect(select, perform)(SettingSystem); export default connect(select, perform)(SettingSystem);

View file

@ -4,11 +4,14 @@ import React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import Card from 'component/common/card'; import Card from 'component/common/card';
import { FormField } from 'component/common/form'; import { FormField } from 'component/common/form';
import FileSelector from 'component/common/file-selector';
import I18nMessage from 'component/i18nMessage';
import SettingAutoLaunch from 'component/settingAutoLaunch'; import SettingAutoLaunch from 'component/settingAutoLaunch';
import SettingClosingBehavior from 'component/settingClosingBehavior'; import SettingClosingBehavior from 'component/settingClosingBehavior';
import SettingCommentsServer from 'component/settingCommentsServer'; import SettingCommentsServer from 'component/settingCommentsServer';
import SettingsRow from 'component/settingsRow'; import SettingsRow from 'component/settingsRow';
import SettingWalletServer from 'component/settingWalletServer'; import SettingWalletServer from 'component/settingWalletServer';
import Spinner from 'component/spinner';
// @if TARGET='app' // @if TARGET='app'
const IS_MAC = process.platform === 'darwin'; const IS_MAC = process.platform === 'darwin';
@ -32,15 +35,46 @@ type DaemonSettings = {
}; };
type Props = { type Props = {
// --- select ---
daemonSettings: DaemonSettings, daemonSettings: DaemonSettings,
ffmpegStatus: { available: boolean, which: string },
findingFFmpeg: boolean,
// --- perform ---
setDaemonSetting: (string, ?SetDaemonSettingArg) => void, setDaemonSetting: (string, ?SetDaemonSettingArg) => void,
clearDaemonSetting: (string) => void,
clearCache: () => Promise<any>, clearCache: () => Promise<any>,
findFFmpeg: () => void,
}; };
export default function SettingSystem(props: Props) { export default function SettingSystem(props: Props) {
const { daemonSettings, setDaemonSetting, clearCache } = props; const {
daemonSettings,
ffmpegStatus,
findingFFmpeg,
setDaemonSetting,
clearDaemonSetting,
clearCache,
findFFmpeg,
} = props;
const [clearingCache, setClearingCache] = React.useState(false); const [clearingCache, setClearingCache] = React.useState(false);
// @if TARGET='app'
const { available: ffmpegAvailable, which: ffmpegPath } = ffmpegStatus;
// @endif
React.useEffect(() => {
// @if TARGET='app'
const { available } = ffmpegStatus;
const { ffmpeg_path: ffmpegPath } = daemonSettings;
if (!available) {
if (ffmpegPath) {
clearDaemonSetting('ffmpeg_path');
}
findFFmpeg();
}
// @endif
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return ( return (
<Card <Card
title={__('System')} title={__('System')}
@ -100,6 +134,69 @@ export default function SettingSystem(props: Props) {
</SettingsRow> </SettingsRow>
{/* @endif */} {/* @endif */}
{/* @if TARGET='app' */}
<SettingsRow
title={
<span>
{__('Automatic transcoding')}
{findingFFmpeg && <Spinner type="small" />}
</span>
}
>
<FileSelector
type="openDirectory"
placeholder={__('A Folder containing FFmpeg')}
currentPath={ffmpegPath || daemonSettings.ffmpeg_path}
onFileChosen={(newDirectory: WebFile) => {
// $FlowFixMe
setDaemonSetting('ffmpeg_path', newDirectory.path);
findFFmpeg();
}}
disabled={Boolean(ffmpegPath)}
/>
<p className="help">
{ffmpegAvailable ? (
<I18nMessage
tokens={{
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://lbry.com/faq/video-publishing-guide#automatic"
/>
),
}}
>
FFmpeg is correctly configured. %learn_more%
</I18nMessage>
) : (
<I18nMessage
tokens={{
check_again: (
<Button
button="link"
label={__('Check again')}
onClick={() => findFFmpeg()}
disabled={findingFFmpeg}
/>
),
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://lbry.com/faq/video-publishing-guide#automatic"
/>
),
}}
>
FFmpeg could not be found. Navigate to it or Install, Then %check_again% or quit and restart the app.
%learn_more%
</I18nMessage>
)}
</p>
</SettingsRow>
{/* @endif */}
{/* @if TARGET='app' */} {/* @if TARGET='app' */}
<SettingsRow title={__('Experimental settings')} useVerticalSeparator> <SettingsRow title={__('Experimental settings')} useVerticalSeparator>
{/* Disabling below until we get downloads to work with shared subscriptions code */} {/* Disabling below until we get downloads to work with shared subscriptions code */}

View file

@ -1,19 +1,8 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doClearCache, doNotifyEncryptWallet, doNotifyDecryptWallet, doNotifyForgetPassword } from 'redux/actions/app'; import { doClearCache, doNotifyEncryptWallet, doNotifyDecryptWallet, doNotifyForgetPassword } from 'redux/actions/app';
import { selectAllowAnalytics } from 'redux/selectors/app'; import { selectAllowAnalytics } from 'redux/selectors/app';
import { import { doSetClientSetting, doEnterSettingsPage, doExitSettingsPage } from 'redux/actions/settings';
doClearDaemonSetting, import { makeSelectClientSetting, selectDaemonSettings } from 'redux/selectors/settings';
doSetClientSetting,
doFindFFmpeg,
doEnterSettingsPage,
doExitSettingsPage,
} from 'redux/actions/settings';
import {
makeSelectClientSetting,
selectDaemonSettings,
selectFfmpegStatus,
selectFindingFFmpeg,
} from 'redux/selectors/settings';
import { doWalletStatus, selectWalletIsEncrypted, SETTINGS } from 'lbry-redux'; import { doWalletStatus, selectWalletIsEncrypted, SETTINGS } from 'lbry-redux';
import SettingsAdvancedPage from './view'; import SettingsAdvancedPage from './view';
import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectUserVerifiedEmail } from 'redux/selectors/user';
@ -24,20 +13,16 @@ const select = (state) => ({
isAuthenticated: selectUserVerifiedEmail(state), isAuthenticated: selectUserVerifiedEmail(state),
walletEncrypted: selectWalletIsEncrypted(state), walletEncrypted: selectWalletIsEncrypted(state),
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
ffmpegStatus: selectFfmpegStatus(state),
findingFFmpeg: selectFindingFFmpeg(state),
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state), syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
}); });
const perform = (dispatch) => ({ const perform = (dispatch) => ({
clearDaemonSetting: (key) => dispatch(doClearDaemonSetting(key)),
clearCache: () => dispatch(doClearCache()), clearCache: () => dispatch(doClearCache()),
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
encryptWallet: () => dispatch(doNotifyEncryptWallet()), encryptWallet: () => dispatch(doNotifyEncryptWallet()),
decryptWallet: () => dispatch(doNotifyDecryptWallet()), decryptWallet: () => dispatch(doNotifyDecryptWallet()),
updateWalletStatus: () => dispatch(doWalletStatus()), updateWalletStatus: () => dispatch(doWalletStatus()),
confirmForgetPassword: (modalProps) => dispatch(doNotifyForgetPassword(modalProps)), confirmForgetPassword: (modalProps) => dispatch(doNotifyForgetPassword(modalProps)),
findFFmpeg: () => dispatch(doFindFFmpeg()),
enterSettings: () => dispatch(doEnterSettingsPage()), enterSettings: () => dispatch(doEnterSettingsPage()),
exitSettings: () => dispatch(doExitSettingsPage()), exitSettings: () => dispatch(doExitSettingsPage()),
}); });

View file

@ -5,11 +5,9 @@ import { FormField } from 'component/common/form';
import Button from 'component/button'; import Button from 'component/button';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
import Page from 'component/page'; import Page from 'component/page';
import FileSelector from 'component/common/file-selector';
import { SETTINGS } from 'lbry-redux'; import { SETTINGS } from 'lbry-redux';
import Card from 'component/common/card'; import Card from 'component/common/card';
import { getPasswordFromCookie } from 'util/saved-passwords'; import { getPasswordFromCookie } from 'util/saved-passwords';
import Spinner from 'component/spinner';
type Price = { type Price = {
currency: string, currency: string,
@ -29,7 +27,6 @@ type DaemonSettings = {
}; };
type Props = { type Props = {
clearDaemonSetting: (string) => void,
setClientSetting: (string, SetDaemonSettingArg) => void, setClientSetting: (string, SetDaemonSettingArg) => void,
daemonSettings: DaemonSettings, daemonSettings: DaemonSettings,
isAuthenticated: boolean, isAuthenticated: boolean,
@ -39,9 +36,6 @@ type Props = {
walletEncrypted: boolean, walletEncrypted: boolean,
hideBalance: boolean, hideBalance: boolean,
confirmForgetPassword: ({}) => void, confirmForgetPassword: ({}) => void,
ffmpegStatus: { available: boolean, which: string },
findingFFmpeg: boolean,
findFFmpeg: () => void,
syncEnabled: boolean, syncEnabled: boolean,
enterSettings: () => void, enterSettings: () => void,
exitSettings: () => void, exitSettings: () => void,
@ -67,18 +61,7 @@ class SettingsAdvancedPage extends React.PureComponent<Props, State> {
} }
componentDidMount() { componentDidMount() {
const { isAuthenticated, ffmpegStatus, daemonSettings, findFFmpeg, enterSettings } = this.props; const { isAuthenticated, enterSettings } = this.props;
// @if TARGET='app'
const { available } = ffmpegStatus;
const { ffmpeg_path: ffmpegPath } = daemonSettings;
if (!available) {
if (ffmpegPath) {
this.clearDaemonSetting('ffmpeg_path');
}
findFFmpeg();
}
// @endif
if (isAuthenticated || !IS_WEB) { if (isAuthenticated || !IS_WEB) {
this.props.updateWalletStatus(); this.props.updateWalletStatus();
@ -96,11 +79,6 @@ class SettingsAdvancedPage extends React.PureComponent<Props, State> {
exitSettings(); exitSettings();
} }
onFFmpegFolder(path: string) {
this.setDaemonSetting('ffmpeg_path', path);
this.findFFmpeg();
}
onThemeChange(event: SyntheticInputEvent<*>) { onThemeChange(event: SyntheticInputEvent<*>) {
const { value } = event.target; const { value } = event.target;
@ -137,30 +115,11 @@ class SettingsAdvancedPage extends React.PureComponent<Props, State> {
// this.props.setDaemonSetting(name, value); // this.props.setDaemonSetting(name, value);
} }
clearDaemonSetting(name: string): void {
this.props.clearDaemonSetting(name);
}
findFFmpeg(): void {
this.props.findFFmpeg();
}
render() { render() {
const { const { daemonSettings, isAuthenticated, walletEncrypted, setClientSetting, hideBalance } = this.props;
daemonSettings,
ffmpegStatus,
isAuthenticated,
walletEncrypted,
setClientSetting,
hideBalance,
findingFFmpeg,
} = this.props;
const { storedPassword } = this.state; const { storedPassword } = this.state;
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
// @if TARGET='app'
const { available: ffmpegAvailable, which: ffmpegPath } = ffmpegStatus;
// @endif
return ( return (
<Page <Page
@ -237,71 +196,6 @@ class SettingsAdvancedPage extends React.PureComponent<Props, State> {
} }
/> />
)} )}
{/* @if TARGET='app' */}
<Card
title={
<span>
{__('Automatic transcoding')}
{findingFFmpeg && <Spinner type="small" />}
</span>
}
actions={
<React.Fragment>
<FileSelector
type="openDirectory"
placeholder={__('A Folder containing FFmpeg')}
currentPath={ffmpegPath || daemonSettings.ffmpeg_path}
onFileChosen={(newDirectory: WebFile) => {
// $FlowFixMe
this.onFFmpegFolder(newDirectory.path);
}}
disabled={Boolean(ffmpegPath)}
/>
<p className="help">
{ffmpegAvailable ? (
<I18nMessage
tokens={{
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://lbry.com/faq/video-publishing-guide#automatic"
/>
),
}}
>
FFmpeg is correctly configured. %learn_more%
</I18nMessage>
) : (
<I18nMessage
tokens={{
check_again: (
<Button
button="link"
label={__('Check again')}
onClick={() => this.findFFmpeg()}
disabled={findingFFmpeg}
/>
),
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://lbry.com/faq/video-publishing-guide#automatic"
/>
),
}}
>
FFmpeg could not be found. Navigate to it or Install, Then %check_again% or quit and restart the
app. %learn_more%
</I18nMessage>
)}
</p>
</React.Fragment>
}
/>
{/* @endif */}
</div> </div>
)} )}
</Page> </Page>