Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/platform/desktop/backend/ipcService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function register() {
return defaults;
});

ipcMain.handle('import-media', async (event, path: string) => {
ipcMain.handle('import-media', async (event, { path }: { path: string }) => {
const updater = (update: DesktopJobUpdate) => {
event.sender.send('job-update', update);
};
Expand Down
33 changes: 28 additions & 5 deletions client/platform/desktop/backend/native/linux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,34 @@ const ViameLinuxConstants = {
kwiverExe: 'kwiver',
shell: '/bin/bash',
ffmpeg: {
// Ready indicates that the proper ffmpeg settings have been learned from the system.
ready: false,
initialization: '', // command to initialize
path: '', // location of the ffmpeg executable
encoding: '', //encoding mode used
// Default video args
videoArgs: [
'-c:v libx264',
'-preset slow',
'-crf 26',
'-c:a copy',
/**
* TODO: Upgrade to ffmpeg 4, use `round` instead of `ceil`
* 3.4 is part of 18.04LTS, so we should support it
*
* References:
* https://github.com/Kitware/dive/pull/602 (Anamorphic Video Support)
* https://video.stackexchange.com/questions/20871/how-do-i-convert-anamorphic-hdv-video-to-normal-h-264-video-with-ffmpeg-how-to
*/
'-vf "scale=ceil(iw*sar/2)*2:ceil(ih/2)*2,setsar=1"',
].join(' '),
},
};

const ViameBundledFFMPEGVideoArgs = [
'-c:v h264',
'-c: a copy',
'-vf "scale=ceil(iw*sar/2)*2:ceil(ih/2)*2,setsar=1"',
].join(' ');

async function validateViamePath(settings: Settings): Promise<true | string> {
const setupScriptPath = npath.join(settings.viamePath, ViameLinuxConstants.setup);
Expand Down Expand Up @@ -127,7 +149,7 @@ async function nvidiaSmi(): Promise<NvidiaSmiReply> {
* Linux version is more complicated for multiple VIAME versions and local ffmpeg
*/
async function ffmpegCommand(settings: Settings) {
if (ViameLinuxConstants.ffmpeg.path !== '' && ViameLinuxConstants.ffmpeg.encoding !== '') {
if (ViameLinuxConstants.ffmpeg.ready) {
return;
}
const setupScriptPath = npath.join(settings.viamePath, ViameLinuxConstants.setup);
Expand All @@ -142,7 +164,7 @@ async function ffmpegCommand(settings: Settings) {
if (viameffmpeg.output.includes('libx264')) {
ViameLinuxConstants.ffmpeg.initialization = `source ${setupScriptPath} &&`;
ViameLinuxConstants.ffmpeg.path = `"${settings.viamePath}/bin/ffmpeg"`;
ViameLinuxConstants.ffmpeg.encoding = '-c:v libx264 -preset slow -crf 26 -c:a copy';
ViameLinuxConstants.ffmpeg.ready = true;
return;
}
}
Expand All @@ -156,7 +178,7 @@ async function ffmpegCommand(settings: Settings) {
if (localffmpeg.output.includes('libx264')) {
ViameLinuxConstants.ffmpeg.initialization = '';
ViameLinuxConstants.ffmpeg.path = 'ffmpeg';
ViameLinuxConstants.ffmpeg.encoding = '-c:v libx264 -preset slow -crf 26 -c:a copy';
ViameLinuxConstants.ffmpeg.ready = true;
return;
}
}
Expand All @@ -168,7 +190,8 @@ async function ffmpegCommand(settings: Settings) {
if (ffmpegViameExists) {
ViameLinuxConstants.ffmpeg.initialization = `source ${setupScriptPath} &&`;
ViameLinuxConstants.ffmpeg.path = `"${settings.viamePath}/bin/ffmpeg"`;
ViameLinuxConstants.ffmpeg.encoding = '-c:v h264 -c:a copy';
ViameLinuxConstants.ffmpeg.videoArgs = ViameBundledFFMPEGVideoArgs;
ViameLinuxConstants.ffmpeg.ready = true;
return;
}
//We make it down here we have no way to convert the video file
Expand Down
40 changes: 29 additions & 11 deletions client/platform/desktop/backend/native/viame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import * as common from './common';
import { cleanString, jobFileEchoMiddleware, spawnResult } from './utils';

const PipelineRelativeDir = 'configs/pipelines';

const DiveJobManifestName = 'dive_job_manifest.json';

interface FFmpegSettings {
initialization: string;
path: string;
encoding: string;
videoArgs: string;
}

interface ViameConstants {
export interface ViameConstants {
setupScriptAbs: string; // abs path setup comman
trainingExe: string; // name of training binary on PATH
kwiverExe: string; // name of kwiver binary on PATH
Expand Down Expand Up @@ -60,7 +60,10 @@ async function runPipeline(

let command: string[] = [];
if (meta.type === 'video') {
const videoAbsPath = npath.join(meta.originalBasePath, meta.originalVideoFile);
let videoAbsPath = npath.join(meta.originalBasePath, meta.originalVideoFile);
if (meta.transcodedVideoFile) {
videoAbsPath = npath.join(projectInfo.basePath, meta.transcodedVideoFile);
}
command = [
`${viameConstants.setupScriptAbs} &&`,
`"${viameConstants.kwiverExe}" runner`,
Expand Down Expand Up @@ -106,7 +109,7 @@ async function runPipeline(
startTime: new Date(),
};

fs.writeFile(npath.join(jobWorkDir, 'dive_job_manifest.json'), JSON.stringify(jobBase));
fs.writeFile(npath.join(jobWorkDir, DiveJobManifestName), JSON.stringify(jobBase));

updater({
...jobBase,
Expand Down Expand Up @@ -244,7 +247,7 @@ async function train(
startTime: new Date(),
};

fs.writeFile(npath.join(jobWorkDir, 'dive_job_manifest.json'), JSON.stringify(jobBase));
fs.writeFile(npath.join(jobWorkDir, DiveJobManifestName), JSON.stringify(jobBase));

updater({
...jobBase,
Expand Down Expand Up @@ -287,14 +290,14 @@ async function checkMedia(
const ffprobePath = `${viameConstants.ffmpeg.path.replace('ffmpeg', 'ffprobe')}`;
const command = [
`${viameConstants.ffmpeg.initialization}`,
`${ffprobePath}`,
`"${ffprobePath}"`,
'-print_format',
'json',
'-v',
'quiet',
'-show_format',
'-show_streams',
file,
`"${file}"`,
];
const result = await spawnResult(command.join(' '), viameConstants.shell);
if (result.error || result.output === null) {
Expand All @@ -303,7 +306,9 @@ async function checkMedia(
const returnText = result.output;
const ffprobeJSON: FFProbeResults = JSON.parse(returnText);
if (ffprobeJSON && ffprobeJSON.streams) {
const websafe = ffprobeJSON.streams.filter((el) => el.codec_name === 'h264' && el.codec_type === 'video');
const websafe = ffprobeJSON.streams
.filter((el) => el.codec_name === 'h264' && el.codec_type === 'video')
.filter((el) => el.sample_aspect_ratio === '1:1');

return !!websafe.length;
}
Expand All @@ -322,7 +327,13 @@ async function convertMedia(settings: Settings,
const joblog = npath.join(jobWorkDir, 'runlog.txt');
const commands = [];
if (args.meta.type === 'video' && args.mediaList[0]) {
commands.push(`${viameConstants.ffmpeg.initialization} ${viameConstants.ffmpeg.path} -i "${args.mediaList[0][0]}" ${viameConstants.ffmpeg.encoding} "${args.mediaList[0][1]}"`);
commands.push([
viameConstants.ffmpeg.initialization,
viameConstants.ffmpeg.path,
`-i "${args.mediaList[0][0]}"`,
viameConstants.ffmpeg.videoArgs,
`"${args.mediaList[0][1]}"`,
].join(' '));
} else if (args.meta.type === 'image-sequence' && imageIndex < args.mediaList.length) {
commands.push(`${viameConstants.ffmpeg.initialization} ${viameConstants.ffmpeg.path} -i "${args.mediaList[imageIndex][0]}" "${args.mediaList[imageIndex][1]}"`);
}
Expand All @@ -345,13 +356,20 @@ async function convertMedia(settings: Settings,
startTime: new Date(),
};

fs.writeFile(npath.join(jobWorkDir, DiveJobManifestName), JSON.stringify(jobBase));

job.stdout.on('data', jobFileEchoMiddleware(jobBase, updater, joblog));
job.stderr.on('data', jobFileEchoMiddleware(jobBase, updater, joblog));


job.on('exit', async (code) => {
Comment thread
BryonLewis marked this conversation as resolved.
if (code !== 0) {
console.error('Error with running conversion');
updater({
...jobBase,
body: [''],
exitCode: code,
endTime: new Date(),
});
} else if (args.meta.type === 'video' || (args.meta.type === 'image-sequence' && imageIndex === args.mediaList.length - 1)) {
common.completeConversion(settings, args.meta.id, jobKey);
updater({
Expand Down
15 changes: 12 additions & 3 deletions client/platform/desktop/backend/native/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,18 @@ const ViameWindowsConstants = {
kwiverExe: 'kwiver.exe',
shell: true,
ffmpeg: {
ready: false,
initialization: '', // command to initialize
path: '', // location of the ffmpeg executable
encoding: '', //encoding mode used
// Default video args
videoArgs: [
'-c:v libx264',
'-preset slow',
'-crf 26',
'-c:a copy',
// https://video.stackexchange.com/questions/20871/how-do-i-convert-anamorphic-hdv-video-to-normal-h-264-video-with-ffmpeg-how-to
'-vf "scale=ceil(iw*sar/2)*2:ceil(ih/2)*2,setsar=1"',
].join(' '),
},

};
Expand Down Expand Up @@ -162,7 +171,7 @@ async function nvidiaSmi(): Promise<NvidiaSmiReply> {
* one time per launch configuration for ffmpeg and ffprobe
*/
async function ffmpegCommand(settings: Settings) {
if (ViameWindowsConstants.ffmpeg.path !== '' && ViameWindowsConstants.ffmpeg.encoding !== '') {
if (ViameWindowsConstants.ffmpeg.ready) {
return;
}
const setupScriptPath = npath.join(settings.viamePath, ViameWindowsConstants.setup);
Expand All @@ -178,7 +187,7 @@ async function ffmpegCommand(settings: Settings) {
if (ffmpegOutput.includes('libx264')) {
ViameWindowsConstants.ffmpeg.initialization = `"${setupScriptPath}" >NUL &&`;
ViameWindowsConstants.ffmpeg.path = `"${settings.viamePath}/bin/ffmpeg.exe"`;
ViameWindowsConstants.ffmpeg.encoding = '-c:v libx264 -preset slow -crf 26 -c:a copy';
ViameWindowsConstants.ffmpeg.ready = true;
return;
}
}
Expand Down
26 changes: 13 additions & 13 deletions client/platform/desktop/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function cleanup() {
app.quit();
}

function createWindow() {
async function createWindow() {
const size = screen.getPrimaryDisplay().workAreaSize;
// Create the browser window.
win = new BrowserWindow({
Expand All @@ -44,9 +44,20 @@ function createWindow() {
},
});

listen((server) => {
let address = server.address();
let port = 0;
if (typeof address === 'object' && address !== null) {
port = address.port || 0;
address = address.address || '';
}
console.error(`Server listening on ${address}:${port}`);
});
ipcListen();

if (process.env.IS_ELECTRON) {
// Load the url of the dev server if in development mode
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string);
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string);
if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
createProtocol('app');
Expand All @@ -57,17 +68,6 @@ function createWindow() {
win.on('closed', () => {
win = null;
});

listen((server) => {
let address = server.address();
let port = 0;
if (typeof address === 'object' && address !== null) {
port = address.port || 0;
address = address.address || '';
}
console.error(`Server listening on ${address}:${port}`);
});
ipcListen();
}

// Quit when all windows are closed.
Expand Down
17 changes: 16 additions & 1 deletion client/platform/desktop/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ export const websafeVideoTypes = [
];

export const otherVideoTypes = [
'video/quicktime',
/* avi */
'vide/avi',
'video/msvideo',
'video/x-msvideo',
'video/x-ms-wmv',
/* mov */
'video/quicktime',
/* mpeg */
'video/mpeg',
'video/x-mpeg',
'video/x-mpeq2a',
/* ogg */
'video/ogg',
];

export const fileVideoTypes = [
Expand All @@ -20,6 +30,10 @@ export const fileVideoTypes = [
'avi',
'mov',
'wmv',
'mpg',
'mpeg',
'mp2',
Comment thread
BryonLewis marked this conversation as resolved.
'ogg',
];

export const websafeImageTypes = [
Expand Down Expand Up @@ -183,6 +197,7 @@ export interface FFProbeResults {
streams?: [{
codec_type?: string;
codec_name?: string;
sample_aspect_ratio?: string;
}];
}

Expand Down
3 changes: 2 additions & 1 deletion client/platform/desktop/frontend/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ async function openFromDisk(datasetType: DatasetType) {
if (datasetType === 'video') {
filters = [
{ name: 'Videos', extensions: fileVideoTypes },
{ name: 'All Files', extensions: ['*'] },
];
}
const results = await remote.dialog.showOpenDialog({
Expand Down Expand Up @@ -72,7 +73,7 @@ async function runTraining(
}

async function importMedia(path: string): Promise<JsonMeta> {
const data: JsonMeta = await ipcRenderer.invoke('import-media', path);
const data: JsonMeta = await ipcRenderer.invoke('import-media', { path });
return data;
}

Expand Down
8 changes: 7 additions & 1 deletion server/dive_server/viame_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ def _get_clip_meta(self, folder):
{
'folderId': folder['_id'],
'meta.codec': 'h264',
'meta.source_video': {'$exists': False},
'meta.source_video': {
'$in': [
# In a previous version, source_video was unset
None,
False,
]
},
}
)
if item:
Expand Down
Loading