fixed issues with video conversion

This commit is contained in:
Rushikesh Tote 2022-02-27 12:04:51 +05:30
parent b861a8d358
commit 6188c9eed4
No known key found for this signature in database
GPG key ID: E4461ACF821B1DA8
3 changed files with 54 additions and 25 deletions

View file

@ -10,6 +10,7 @@ class FFmpegService {
private fileReader: FileReader = null;
private generateThumbnailProcessor = new QueueProcessor<Uint8Array>(1);
private generateMP4ConversionProcessor = new QueueProcessor<Uint8Array>(1);
async init() {
try {
this.ffmpeg = createFFmpeg({
@ -57,7 +58,10 @@ class FFmpegService {
}
}
async convertLivePhotoToMP4(file: Uint8Array): Promise<Uint8Array> {
async convertToMP4(
file: Uint8Array,
fileName: string
): Promise<Uint8Array> {
if (!this.ffmpeg) {
await this.init();
}
@ -65,30 +69,23 @@ class FFmpegService {
await this.isLoading;
}
const response = this.generateMP4ConversionProcessor.queueUpRequest(
convertToMP4Helper.bind(null, this.ffmpeg, file, fileName)
);
try {
this.ffmpeg.FS('writeFile', 'input.mov', file);
console.log('starting encoding', new Date().toLocaleTimeString());
await this.ffmpeg.run(
'-i',
'input.mov',
'-preset',
'ultrafast',
'output.mp4'
);
const convertedFile = await this.ffmpeg.FS(
'readFile',
'output.mp4'
);
console.log('done encoding', new Date().toLocaleTimeString());
await this.ffmpeg.FS('unlink', 'input.mov');
await this.ffmpeg.FS('unlink', 'output.mp4');
return convertedFile;
return await response.promise;
} catch (e) {
logError(e, 'ffmpeg live photo to MP4 conversion failed');
if (e.message === CustomError.REQUEST_CANCELLED) {
// ignore
return null;
} else {
logError(e, 'ffmpeg MP4 conversion failed');
throw e;
}
}
}
}
async function generateThumbnailHelper(
ffmpeg: FFmpeg,
@ -133,4 +130,28 @@ async function generateThumbnailHelper(
}
}
async function convertToMP4Helper(
ffmpeg: FFmpeg,
file: Uint8Array,
inputFileName: string
) {
try {
ffmpeg.FS('writeFile', inputFileName, file);
await ffmpeg.run(
'-i',
inputFileName,
'-preset',
'ultrafast',
'output.mp4'
);
const convertedFile = await ffmpeg.FS('readFile', 'output.mp4');
ffmpeg.FS('unlink', inputFileName);
ffmpeg.FS('unlink', 'output.mp4');
return convertedFile;
} catch (e) {
logError(e, 'ffmpeg MP4 conversion failed');
throw e;
}
}
export default new FFmpegService();

View file

@ -1,6 +1,5 @@
import JSZip from 'jszip';
import { fileExtensionWithDot } from 'utils/file';
import FFmpegService from 'services/ffmpegService';
class MotionPhoto {
image: Uint8Array;
@ -26,9 +25,8 @@ export const decodeMotionPhoto = async (
} else if (zipFilename.startsWith('video')) {
motionPhoto.videoNameTitle =
originalName + fileExtensionWithDot(zipFilename);
const video = await zip.files[zipFilename].async('uint8array');
motionPhoto.video = await FFmpegService.convertLivePhotoToMP4(
video
motionPhoto.video = await zip.files[zipFilename].async(
'uint8array'
);
}
}

View file

@ -24,6 +24,7 @@ import {
} from 'constants/file';
import PublicCollectionDownloadManager from 'services/publicCollectionDownloadManager';
import HEICConverter from 'services/HEICConverter';
import ffmpegService from 'services/ffmpegService';
export function downloadAsFile(filename: string, content: string) {
const file = new Blob([content], {
@ -353,7 +354,13 @@ export async function splitLivePhoto(file: EnteFile, url: string) {
const originalName = fileNameWithoutExtension(file.metadata.title);
const motionPhoto = await decodeMotionPhoto(fileBlob, originalName);
let image = new Blob([motionPhoto.image]);
const video = new Blob([motionPhoto.video]);
// can run conversion in parellel as video and image
// have different processes
const convertedVideo = ffmpegService.convertToMP4(
motionPhoto.video,
motionPhoto.videoNameTitle
);
const typeFromExtension = getFileExtension(motionPhoto.imageNameTitle);
const reader = new FileReader();
@ -363,6 +370,9 @@ export async function splitLivePhoto(file: EnteFile, url: string) {
if (isFileHEIC(mimeType)) {
image = await HEICConverter.convert(image);
}
const video = new Blob([await convertedVideo]);
const imageURL = URL.createObjectURL(image);
const videoURL = URL.createObjectURL(video);
return { imageURL, videoURL };