From e35fbdd86ae6dd93ab0c3947efe7bb96e8de0331 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 24 Mar 2020 13:57:17 -0400 Subject: [PATCH] make transcoding work appstrings provide optimize checkbox on publish fix missing status no crash on web cleanup better settings ui add help and time estimate to publish transcoding messaging fix: Special SDK + fix config name fix: older SDK build fix app string, style tweak whoops, and looks better to me this way. bump SDK --- flow-typed/web-file.js | 2 +- package.json | 2 +- static/app-strings.json | 8 ++- ui/component/publishFile/index.js | 3 + ui/component/publishFile/view.jsx | 72 ++++++++++++++++++++- ui/component/publishForm/view.jsx | 71 +++++++++++---------- ui/constants/action_types.js | 2 + ui/page/settings/index.js | 20 +++++- ui/page/settings/view.jsx | 102 ++++++++++++++++++++++++++++-- ui/redux/actions/app.js | 4 ++ ui/redux/actions/settings.js | 13 ++++ ui/redux/reducers/publish.js | 1 - ui/redux/reducers/settings.js | 13 +++- ui/redux/selectors/settings.js | 13 +++- ui/scss/init/_gui.scss | 3 +- 15 files changed, 279 insertions(+), 50 deletions(-) delete mode 100644 ui/redux/reducers/publish.js diff --git a/flow-typed/web-file.js b/flow-typed/web-file.js index afc6bf195..08f995d43 100644 --- a/flow-typed/web-file.js +++ b/flow-typed/web-file.js @@ -1,7 +1,7 @@ declare type WebFile = { name: string, title?: string, - path?: string, + path: string, size: string, type: string, } diff --git a/package.json b/package.json index b39880075..43ce9505e 100644 --- a/package.json +++ b/package.json @@ -209,7 +209,7 @@ "yarn": "^1.3" }, "lbrySettings": { - "lbrynetDaemonVersion": "0.64.0", + "lbrynetDaemonVersion": "0.65.0", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip", "lbrynetDaemonDir": "static/daemon", "lbrynetDaemonFileName": "lbrynet" diff --git a/static/app-strings.json b/static/app-strings.json index 0a09c8529..01e87d204 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1027,6 +1027,12 @@ "For video content, use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.": "For video content, use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.", "Your video may not be the best format. Use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.": "Your video may not be the best format. Use MP4s in H264/AAC format and a friendly bitrate (720p) for more reliable streaming.", "Your video has a bitrate over 6 mbps. We suggest transcoding to provide viewers the best experience.": "Your video has a bitrate over 6 mbps. We suggest transcoding to provide viewers the best experience.", + "Transcoding": "Transcoding", + "Optimize and transcode video": "Optimize and transcode video", + "FFmpeg not found": "FFmpeg not found", + "FFmpeg is correctly configured": "FFmpeg is correctly configured", + "ffmpeg not found": "ffmpeg not found", + "Known Tags": "Known Tags", "Your video has a bitrate over 5 mbps. We suggest transcoding to provide viewers the best experience.": "Your video has a bitrate over 5 mbps. We suggest transcoding to provide viewers the best experience.", "Almost there": "Almost there", "More Channels": "More Channels", @@ -1072,4 +1078,4 @@ "You are currently following %followingCount% tags": "You are currently following %followingCount% tags", "Back": "Back", "Nice! You are currently following %followingCount% creators": "Nice! You are currently following %followingCount% creators" -} \ No newline at end of file +} diff --git a/ui/component/publishFile/index.js b/ui/component/publishFile/index.js index 30d533097..e1e0f6878 100644 --- a/ui/component/publishFile/index.js +++ b/ui/component/publishFile/index.js @@ -7,14 +7,17 @@ import { doToast, doClearPublish, } from 'lbry-redux'; +import { selectFfmpegStatus } from 'redux/selectors/settings'; import PublishPage from './view'; const select = state => ({ name: makeSelectPublishFormValue('name')(state), filePath: makeSelectPublishFormValue('filePath')(state), + optimize: makeSelectPublishFormValue('optimize')(state), isStillEditing: selectIsStillEditing(state), balance: selectBalance(state), publishing: makeSelectPublishFormValue('publishing')(state), + ffmpegStatus: selectFfmpegStatus(state), }); const perform = dispatch => ({ diff --git a/ui/component/publishFile/view.jsx b/ui/component/publishFile/view.jsx index 1d846ad0c..4a9d744e5 100644 --- a/ui/component/publishFile/view.jsx +++ b/ui/component/publishFile/view.jsx @@ -5,7 +5,9 @@ import { regexInvalidURI } from 'lbry-redux'; import FileSelector from 'component/common/file-selector'; import Button from 'component/button'; import Card from 'component/common/card'; +import { FormField } from 'component/common/form'; import Spinner from 'component/spinner'; +import I18nMessage from '../i18nMessage'; type Props = { name: ?string, @@ -18,6 +20,8 @@ type Props = { showToast: string => void, inProgress: boolean, clearPublish: () => void, + ffmpegStatus: any, + optimize: boolean, }; function PublishFile(props: Props) { @@ -31,8 +35,11 @@ function PublishFile(props: Props) { publishing, inProgress, clearPublish, + optimize, + ffmpegStatus = {}, } = props; + const { available } = ffmpegStatus; const [duration, setDuration] = useState(0); const [size, setSize] = useState(0); const [oversized, setOversized] = useState(false); @@ -40,6 +47,12 @@ function PublishFile(props: Props) { const RECOMMENDED_BITRATE = 6000000; const TV_PUBLISH_SIZE_LIMIT: number = 1073741824; const UPLOAD_SIZE_MESSAGE = 'Lbrytv uploads are limited to 1 GB. Download the app for unrestricted publishing.'; + const PROCESSING_MB_PER_SECOND = 0.5; + const MINUTES_THRESHOLD = 30; + const HOURS_THRESHOLD = MINUTES_THRESHOLD * 60; + + const sizeInMB = Number(size) / 1000000; + const secondsToProcess = sizeInMB / PROCESSING_MB_PER_SECOND; // clear warnings useEffect(() => { @@ -70,6 +83,29 @@ function PublishFile(props: Props) { } } + function getTimeForMB(s) { + if (s < MINUTES_THRESHOLD) { + return Math.floor(secondsToProcess); + } else if (s >= MINUTES_THRESHOLD && s < HOURS_THRESHOLD) { + return Math.floor(secondsToProcess / 60); + } else { + return Math.floor(secondsToProcess / 60 / 60); + } + } + + function getUnitsForMB(s) { + if (s < MINUTES_THRESHOLD) { + if (secondsToProcess > 1) return 'seconds'; + return 'second'; + } else if (s >= MINUTES_THRESHOLD && s < HOURS_THRESHOLD) { + if (Math.floor(secondsToProcess / 60) > 1) return 'minutes'; + return 'minute'; + } else { + if (Math.floor(secondsToProcess / 3600) > 1) return 'hours'; + return 'hour'; + } + } + function getMessage() { // @if TARGET='web' if (oversized) { @@ -189,7 +225,7 @@ function PublishFile(props: Props) { } // @endif - const publishFormParams: { filePath: string | WebFile, name?: string } = { + const publishFormParams: { filePath: string | WebFile, name?: string, optimize?: boolean } = { filePath: file.path || file, }; // Strip off extention and replace invalid characters @@ -232,6 +268,40 @@ function PublishFile(props: Props) { {getMessage()} + {/* @if TARGET='app' */} + updatePublishForm({ optimize: e.target.checked })} + label={__('Optimize and transcode video')} + name="optimize" + /> + {!available && ( +

+ , + }} + > + FFmpeg not configured. More in %settings_link%. + +

+ )} + {Boolean(size) && available && optimize && isVid && ( +

+ + Transcoding this %size%MB file should take under %processTime% %units%. + +

+ )} + {/* @endif */}
} /> diff --git a/ui/component/publishForm/view.jsx b/ui/component/publishForm/view.jsx index 29c92f9d9..a0ef130c7 100644 --- a/ui/component/publishForm/view.jsx +++ b/ui/component/publishForm/view.jsx @@ -143,9 +143,10 @@ function PublishForm(props: Props) { return ( -
- - } /> + {!publishing && ( +
+ + } /> - - updatePublishForm({ channel })} /> -

- {__('This is a username or handle that your content can be found under.')}{' '} - {__('Ex. @Marvel, @TheBeatles, @BooksByJoe')} -

- - } - /> + + updatePublishForm({ channel })} /> +

+ {__('This is a username or handle that your content can be found under.')}{' '} + {__('Ex. @Marvel, @TheBeatles, @BooksByJoe')} +

+ + } + /> - - - + + + +
+ )} +
+ {!formDisabled && !formValid && } -
- {!formDisabled && !formValid && } - -
-
-

- {__('By continuing, you accept the')}{' '} -

-
+
+
+

+ {__('By continuing, you accept the')}{' '} +