kopia lustrzana https://github.com/mifi/lossless-cut
rodzic
6126848e19
commit
55f2eb83ca
|
@ -1410,7 +1410,7 @@ const App = memo(() => {
|
|||
const fileMeta = await readFileMeta(fp);
|
||||
// console.log('file meta read', fileMeta);
|
||||
|
||||
const fileFormatNew = await getSmarterOutFormat(fp, fileMeta.format);
|
||||
const fileFormatNew = await getSmarterOutFormat({ filePath: fp, fileMeta });
|
||||
|
||||
// console.log(streams, fileMeta.format, fileFormat);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ const ConcatDialog = memo(({
|
|||
setFileFormat();
|
||||
setDetectedFileFormat();
|
||||
const fileMetaNew = await readFileMeta(firstPath);
|
||||
const fileFormatNew = await getSmarterOutFormat(firstPath, fileMetaNew.format);
|
||||
const fileFormatNew = await getSmarterOutFormat({ filePath: firstPath, fileMeta: fileMetaNew });
|
||||
if (aborted) return;
|
||||
setFileMeta(fileMetaNew);
|
||||
setFileFormat(fileFormatNew);
|
||||
|
|
|
@ -6,6 +6,7 @@ import i18n from 'i18next';
|
|||
import Timecode from 'smpte-timecode';
|
||||
|
||||
import { getOutPath, isDurationValid, getExtensionForFormat, isWindows, platform } from './util';
|
||||
import { encodeablePcmCodecs } from './util/streams';
|
||||
|
||||
const execa = window.require('execa');
|
||||
const { join } = window.require('path');
|
||||
|
@ -228,13 +229,20 @@ export async function createChaptersFromSegments({ segmentPaths, chapterNames })
|
|||
* Therefore we have to map between detected format and encode format
|
||||
* See also ffmpeg -formats
|
||||
*/
|
||||
function mapFormat(requestedFormat) {
|
||||
function mapDefaultFormat({ streams, requestedFormat }) {
|
||||
if (requestedFormat === 'mp4') {
|
||||
// Only MOV supports these, so switch to MOV https://github.com/mifi/lossless-cut/issues/948
|
||||
if (streams.some((stream) => encodeablePcmCodecs.includes(stream.codec_name))) {
|
||||
return 'mov';
|
||||
}
|
||||
}
|
||||
|
||||
switch (requestedFormat) {
|
||||
// These two cmds produce identical output, so we assume that encoding "ipod" means encoding m4a
|
||||
// ffmpeg -i example.aac -c copy OutputFile2.m4a
|
||||
// ffmpeg -i example.aac -c copy -f ipod OutputFile.m4a
|
||||
// See also https://github.com/mifi/lossless-cut/issues/28
|
||||
case 'm4a': return 'ipod';
|
||||
case 'm4a':
|
||||
case 'aac': return 'ipod';
|
||||
default: return requestedFormat;
|
||||
}
|
||||
|
@ -245,8 +253,8 @@ function determineOutputFormat(ffprobeFormats, fileTypeResponse) {
|
|||
return ffprobeFormats[0] || undefined;
|
||||
}
|
||||
|
||||
export async function getSmarterOutFormat(filePath, formatData) {
|
||||
const formatsStr = formatData.format_name;
|
||||
export async function getSmarterOutFormat({ filePath, fileMeta: { format, streams } }) {
|
||||
const formatsStr = format.format_name;
|
||||
console.log('formats', formatsStr);
|
||||
const formats = (formatsStr || '').split(',');
|
||||
|
||||
|
@ -254,12 +262,9 @@ export async function getSmarterOutFormat(filePath, formatData) {
|
|||
const bytes = await readChunk(filePath, 0, 4100);
|
||||
const fileTypeResponse = fileType(bytes) || {};
|
||||
console.log(`fileType detected format ${JSON.stringify(fileTypeResponse)}`);
|
||||
let assumedFormat = determineOutputFormat(formats, fileTypeResponse);
|
||||
const assumedFormat = determineOutputFormat(formats, fileTypeResponse);
|
||||
|
||||
// https://github.com/mifi/lossless-cut/issues/367
|
||||
if (assumedFormat === 'mp4' && formatData.tags && formatData.tags.major_brand === 'XAVC') assumedFormat = 'mov';
|
||||
|
||||
return mapFormat(assumedFormat);
|
||||
return mapDefaultFormat({ streams, requestedFormat: assumedFormat });
|
||||
}
|
||||
|
||||
export async function readFileMeta(filePath) {
|
||||
|
|
|
@ -6,6 +6,57 @@ export const defaultProcessedCodecTypes = [
|
|||
'attachment',
|
||||
];
|
||||
|
||||
// taken from `ffmpeg -codecs`
|
||||
export const encodeablePcmCodecs = [
|
||||
'adpcm_adx',
|
||||
'adpcm_argo',
|
||||
'adpcm_g722',
|
||||
'adpcm_g726',
|
||||
'adpcm_g726le',
|
||||
'adpcm_ima_alp',
|
||||
'adpcm_ima_amv',
|
||||
'adpcm_ima_apm',
|
||||
'adpcm_ima_qt',
|
||||
'adpcm_ima_ssi',
|
||||
'adpcm_ima_wav',
|
||||
'adpcm_ms',
|
||||
'adpcm_swf',
|
||||
'adpcm_yamaha',
|
||||
|
||||
'pcm_alaw',
|
||||
'pcm_dvd',
|
||||
|
||||
'pcm_f32be',
|
||||
'pcm_f32le',
|
||||
'pcm_f64be',
|
||||
'pcm_f64le',
|
||||
|
||||
'pcm_mulaw',
|
||||
'pcm_s16be',
|
||||
'pcm_s16be_planar',
|
||||
'pcm_s16le',
|
||||
'pcm_s16le_planar',
|
||||
'pcm_s24be',
|
||||
'pcm_s24daud',
|
||||
'pcm_s24le',
|
||||
'pcm_s24le_planar',
|
||||
'pcm_s32be',
|
||||
'pcm_s32le',
|
||||
'pcm_s32le_planar',
|
||||
'pcm_s64be',
|
||||
'pcm_s64le',
|
||||
'pcm_s8',
|
||||
'pcm_s8_planar',
|
||||
'pcm_u16be',
|
||||
'pcm_u16le',
|
||||
'pcm_u24be',
|
||||
'pcm_u24le',
|
||||
'pcm_u32be',
|
||||
'pcm_u32le',
|
||||
'pcm_u8',
|
||||
'pcm_vidc',
|
||||
];
|
||||
|
||||
export function getActiveDisposition(disposition) {
|
||||
if (disposition == null) return undefined;
|
||||
const existingActiveDispositionEntry = Object.entries(disposition).find(([, value]) => value === 1);
|
||||
|
|
|
@ -17,7 +17,7 @@ const streams1 = [
|
|||
// https://stackoverflow.com/questions/32152090/encode-h265-to-hvc1-codec
|
||||
test('getMapStreamsArgs', () => {
|
||||
const path = '/path/file.mp4';
|
||||
const outFormat = 'mp4';
|
||||
const outFormat = 'mp4';
|
||||
|
||||
expect(getMapStreamsArgs({
|
||||
allFilesMeta: { [path]: { streams: streams1 } },
|
||||
|
|
Ładowanie…
Reference in New Issue