Added Online converter

This commit is contained in:
Jonas Kamsker 2021-05-17 22:24:14 +02:00
parent daab4fa3d8
commit 20410b3bda
5 changed files with 90 additions and 11 deletions

View file

@ -5,11 +5,14 @@
"version": "0.1.0",
"dependencies": {
"@babel/core": "^7.13.13",
"@ffmpeg/core": "^0.9.0",
"@ffmpeg/ffmpeg": "^0.9.8",
"@material-ui/core": "^4.11.3",
"@material-ui/icons": "^4.11.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"fork-me-on-github": "^1.0.6",
"react": "^16.14.0",
"react-copy-to-clipboard": "^5.0.3",
"react-dom": "^16.14.0",

View file

@ -25,7 +25,7 @@ import { FilePicker } from '../src/Components'
import { CopyToClipboard } from 'react-copy-to-clipboard';
import ControlledAccordions from './ControlledAccordions'
import OnlineConverter from "./OnlineConverter";
import 'react-notifications-component/dist/theme.css'
import ReactNotification from 'react-notifications-component'
@ -179,7 +179,7 @@ class ChecksumResolver extends React.Component {
// return;
// }
this.setState({ fileName: file.name });
this.setState({ fileName: file.name, file:file });
const slic = file.slice(653, 653 + 20);
const results = this.buf2hex(await slic.arrayBuffer());
this.setChecksum(results)
@ -189,7 +189,7 @@ class ChecksumResolver extends React.Component {
render() {
const { classes } = this.props;
const { checksum, activationBytes, fileName } = this.state;
const { checksum, activationBytes, fileName, file } = this.state;
// const { files, onClick, errors, HiddenFileInput } = useFilePicker({
// maxFileSize: 1000000,
@ -296,6 +296,7 @@ class ChecksumResolver extends React.Component {
<ControlledAccordions
fileName={fileName}
activationBytes={activationBytes}
file ={file}
/>
<Box mt={1}>
<this.Copyright />

View file

@ -21,6 +21,7 @@ import { Radio, RadioGroup } from '@material-ui/core';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
import OnlineConverter from "./OnlineConverter";
class ControlledAccordions extends React.Component {
constructor(props) {
@ -71,7 +72,7 @@ class ControlledAccordions extends React.Component {
{ os: "osx", cmd: "./ffmpeg", discriminator: '\'' },
];
let fileNameWithoutExtension = fileName.split('.')[0];
let fileNameWithoutExtension = fileName.split('.').slice(0, -1).join('.');
fileNameWithoutExtension = fileNameWithoutExtension == 'input' ? 'output' : fileNameWithoutExtension;
const osMap = osToBinMaps.filter(x => x.os == operatingSystem)[0];
@ -89,10 +90,8 @@ class ControlledAccordions extends React.Component {
}
render() {
const { classes } = this.props;
const { classes, file, activationBytes} = this.props;
const { expanded, outputFormat, operatingSystem } = this.state;
return (
<div className={classes.root}>
<Accordion expanded={expanded === 'panel2'} onChange={this.handleChange('panel2')}>
@ -101,9 +100,9 @@ class ControlledAccordions extends React.Component {
aria-controls="panel2bh-content"
id="panel2bh-header"
>
<Typography className={classes.heading}>Command</Typography>
<Typography className={classes.heading}>Command and Convert</Typography>
<Typography className={classes.secondaryHeading}>
Generate ffmpeg command
Generate ffmpeg command or convert in browser
</Typography>
</AccordionSummary>
<AccordionDetails style={{ display: 'block' }}>
@ -144,6 +143,9 @@ class ControlledAccordions extends React.Component {
}}
/>
<OnlineConverter file={file}
activationBytes={activationBytes}
outputFormat = {outputFormat}/>
</AccordionDetails>
</Accordion>
</div>

67
src/OnlineConverter.jsx Normal file
View file

@ -0,0 +1,67 @@
import React, {useState} from "react";
import Button from '@material-ui/core/Button';
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
import Typography from "@material-ui/core/Typography";
const downloadFile= (data, outputFileName, outputFormat) => {
let a = document.createElement("a");
document.body.appendChild(a);
const blob = new Blob([data.buffer], { type: 'audio/'+outputFormat});
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = outputFileName;
a.click();
window.URL.revokeObjectURL(url);
}
const getCommandAsList = (file, outputFileName, outputFormat, activationBytes) =>{
const outputFormatCodecMaps = [
{ format: "m4b", codec: "copy" },
{ format: "flac", codec: "flac" },
{ format: "mp3", codec: "libmp3lame" },
];
const codec = outputFormatCodecMaps.filter(x => x.format === outputFormat)[0].codec;
const filename = file.name;
return [`-y`,
'-activation_bytes', activationBytes,
'-i', filename,
'-c:a', codec,
'-vn', outputFileName
];
}
const doTranscode = async (file, outputFileName, outputFormat, activationBytes, setMessage) => {
const ffmpeg = createFFmpeg({
log: true,
progress: ({ ratio }) => {
setMessage(`Complete: ${(ratio * 100.0).toFixed(2)}%`);
}
});
const command = getCommandAsList(file, outputFileName, outputFormat, activationBytes);
setMessage('Loading ffmpeg-core.js');
await ffmpeg.load();
setMessage('Start transcoding');
ffmpeg.FS('writeFile', file.name, await fetchFile(file));
await ffmpeg.run(...command);
setMessage('Complete transcoding');
const data = ffmpeg.FS('readFile', outputFileName);
downloadFile(data,outputFileName, outputFormat)
};
const OnlineConverter = (props) => {
const {file, activationBytes, outputFormat} = props
const [message, setMessage] = useState('Click Start to transcode');
const downloadDisabled = !(file && activationBytes && outputFormat)
return(
<div>
<Button onClick={()=>{
let fileNameWithoutExtension = file.name.split('.').slice(0, -1).join('.');
fileNameWithoutExtension = fileNameWithoutExtension === 'input' ? 'output' : fileNameWithoutExtension;
const outputFileName = `${fileNameWithoutExtension}.${outputFormat}`
return doTranscode(file,outputFileName,outputFormat,activationBytes,setMessage)
}} variant="contained" color="primary" disabled={downloadDisabled}>Convert in Browser</Button>
<Typography>{message}</Typography>
</div>
)
}
export default OnlineConverter

View file

@ -4,6 +4,8 @@ import './index.css';
import * as serviceWorker from './serviceWorker';
import ChecksumResolver from './ChecksumResolver';
import ReactNotification from 'react-notifications-component'
import ForkMeOnGithub from 'fork-me-on-github';
import ReactGA from 'react-ga';
ReactGA.initialize('UA-174657678-1');
@ -15,7 +17,11 @@ ReactDOM.render(
<ReactNotification />
</div>
<ForkMeOnGithub
repo="https://github.com/audible-tools/audible-tools.github.io"
colorOctocat="black"
isPride
/>
<ChecksumResolver />
</div>,
document.getElementById('root')