@@ -30,6 +30,12 @@ import {
3030 isComboInputSpecV1 ,
3131 isComboInputSpecV2
3232} from '@/schemas/nodeDefSchema'
33+ import { getFromWebmFile } from '@/scripts/metadata/ebml'
34+ import { getGltfBinaryMetadata } from '@/scripts/metadata/gltf'
35+ import { getFromIsobmffFile } from '@/scripts/metadata/isobmff'
36+ import { getMp3Metadata } from '@/scripts/metadata/mp3'
37+ import { getOggMetadata } from '@/scripts/metadata/ogg'
38+ import { getSvgMetadata } from '@/scripts/metadata/svg'
3339import { useDialogService } from '@/services/dialogService'
3440import { useExtensionService } from '@/services/extensionService'
3541import { useLitegraphService } from '@/services/litegraphService'
@@ -67,7 +73,13 @@ import { deserialiseAndCreate } from '@/utils/vintageClipboard'
6773import { type ComfyApi , PromptExecutionError , api } from './api'
6874import { defaultGraph } from './defaultGraph'
6975import { pruneWidgets } from './domWidget'
70- import { importA1111 } from './pnginfo'
76+ import {
77+ getFlacMetadata ,
78+ getLatentMetadata ,
79+ getPngMetadata ,
80+ getWebpMetadata ,
81+ importA1111
82+ } from './pnginfo'
7183import { $el , ComfyUI } from './ui'
7284import { ComfyAppMenu } from './ui/menu/index'
7385import { clone } from './utils'
@@ -1265,52 +1277,168 @@ export class ComfyApp {
12651277 * @param {File } file
12661278 */
12671279 async handleFile ( file : File ) {
1268- const { getFileHandler } = await import ( '@/utils/fileHandlers' )
12691280 const removeExt = ( f : string ) => {
12701281 if ( ! f ) return f
12711282 const p = f . lastIndexOf ( '.' )
12721283 if ( p === - 1 ) return f
12731284 return f . substring ( 0 , p )
12741285 }
12751286 const fileName = removeExt ( file . name )
1276-
1277- // Get the appropriate file handler for this file type
1278- const fileHandler = getFileHandler ( file )
1279-
1280- if ( ! fileHandler ) {
1281- // No handler found for this file type
1282- this . showErrorOnFileLoad ( file )
1283- return
1284- }
1285-
1286- try {
1287- // Process the file using the handler
1288- const { workflow, prompt, parameters, jsonTemplateData } =
1289- await fileHandler ( file )
1290-
1291- if ( workflow ) {
1292- // We have a workflow, load it
1293- await this . loadGraphData ( workflow , true , true , fileName )
1294- } else if ( prompt ) {
1295- // We have a prompt in API format, load it
1296- this . loadApiJson ( prompt , fileName )
1297- } else if ( parameters ) {
1298- // We have A1111 parameters, import them
1287+ if ( file . type === 'image/png' ) {
1288+ const pngInfo = await getPngMetadata ( file )
1289+ if ( pngInfo ?. workflow ) {
1290+ await this . loadGraphData (
1291+ JSON . parse ( pngInfo . workflow ) ,
1292+ true ,
1293+ true ,
1294+ fileName
1295+ )
1296+ } else if ( pngInfo ?. prompt ) {
1297+ this . loadApiJson ( JSON . parse ( pngInfo . prompt ) , fileName )
1298+ } else if ( pngInfo ?. parameters ) {
1299+ // Note: Not putting this in `importA1111` as it is mostly not used
1300+ // by external callers, and `importA1111` has no access to `app`.
12991301 useWorkflowService ( ) . beforeLoadNewGraph ( )
1300- importA1111 ( this . graph , parameters )
1302+ importA1111 ( this . graph , pngInfo . parameters )
13011303 useWorkflowService ( ) . afterLoadNewGraph (
13021304 fileName ,
13031305 this . graph . serialize ( ) as unknown as ComfyWorkflowJSON
13041306 )
1305- } else if ( jsonTemplateData ) {
1306- // We have template data from JSON
1307- this . loadTemplateData ( jsonTemplateData )
13081307 } else {
1309- // No usable data found in the file
13101308 this . showErrorOnFileLoad ( file )
13111309 }
1312- } catch ( error ) {
1313- console . error ( 'Error processing file:' , error )
1310+ } else if ( file . type === 'image/webp' ) {
1311+ const pngInfo = await getWebpMetadata ( file )
1312+ // Support loading workflows from that webp custom node.
1313+ const workflow = pngInfo ?. workflow || pngInfo ?. Workflow
1314+ const prompt = pngInfo ?. prompt || pngInfo ?. Prompt
1315+
1316+ if ( workflow ) {
1317+ this . loadGraphData ( JSON . parse ( workflow ) , true , true , fileName )
1318+ } else if ( prompt ) {
1319+ this . loadApiJson ( JSON . parse ( prompt ) , fileName )
1320+ } else {
1321+ this . showErrorOnFileLoad ( file )
1322+ }
1323+ } else if ( file . type === 'audio/mpeg' ) {
1324+ const { workflow, prompt } = await getMp3Metadata ( file )
1325+ if ( workflow ) {
1326+ this . loadGraphData ( workflow , true , true , fileName )
1327+ } else if ( prompt ) {
1328+ this . loadApiJson ( prompt , fileName )
1329+ } else {
1330+ this . showErrorOnFileLoad ( file )
1331+ }
1332+ } else if ( file . type === 'audio/ogg' ) {
1333+ const { workflow, prompt } = await getOggMetadata ( file )
1334+ if ( workflow ) {
1335+ this . loadGraphData ( workflow , true , true , fileName )
1336+ } else if ( prompt ) {
1337+ this . loadApiJson ( prompt , fileName )
1338+ } else {
1339+ this . showErrorOnFileLoad ( file )
1340+ }
1341+ } else if ( file . type === 'audio/flac' || file . type === 'audio/x-flac' ) {
1342+ const pngInfo = await getFlacMetadata ( file )
1343+ const workflow = pngInfo ?. workflow || pngInfo ?. Workflow
1344+ const prompt = pngInfo ?. prompt || pngInfo ?. Prompt
1345+
1346+ if ( workflow ) {
1347+ this . loadGraphData ( JSON . parse ( workflow ) , true , true , fileName )
1348+ } else if ( prompt ) {
1349+ this . loadApiJson ( JSON . parse ( prompt ) , fileName )
1350+ } else {
1351+ this . showErrorOnFileLoad ( file )
1352+ }
1353+ } else if ( file . type === 'video/webm' ) {
1354+ const webmInfo = await getFromWebmFile ( file )
1355+ if ( webmInfo . workflow ) {
1356+ this . loadGraphData ( webmInfo . workflow , true , true , fileName )
1357+ } else if ( webmInfo . prompt ) {
1358+ this . loadApiJson ( webmInfo . prompt , fileName )
1359+ } else {
1360+ this . showErrorOnFileLoad ( file )
1361+ }
1362+ } else if (
1363+ file . type === 'video/mp4' ||
1364+ file . name ?. endsWith ( '.mp4' ) ||
1365+ file . name ?. endsWith ( '.mov' ) ||
1366+ file . name ?. endsWith ( '.m4v' ) ||
1367+ file . type === 'video/quicktime' ||
1368+ file . type === 'video/x-m4v'
1369+ ) {
1370+ const mp4Info = await getFromIsobmffFile ( file )
1371+ if ( mp4Info . workflow ) {
1372+ this . loadGraphData ( mp4Info . workflow , true , true , fileName )
1373+ } else if ( mp4Info . prompt ) {
1374+ this . loadApiJson ( mp4Info . prompt , fileName )
1375+ }
1376+ } else if ( file . type === 'image/svg+xml' || file . name ?. endsWith ( '.svg' ) ) {
1377+ const svgInfo = await getSvgMetadata ( file )
1378+ if ( svgInfo . workflow ) {
1379+ this . loadGraphData ( svgInfo . workflow , true , true , fileName )
1380+ } else if ( svgInfo . prompt ) {
1381+ this . loadApiJson ( svgInfo . prompt , fileName )
1382+ } else {
1383+ this . showErrorOnFileLoad ( file )
1384+ }
1385+ } else if (
1386+ file . type === 'model/gltf-binary' ||
1387+ file . name ?. endsWith ( '.glb' )
1388+ ) {
1389+ const gltfInfo = await getGltfBinaryMetadata ( file )
1390+ if ( gltfInfo . workflow ) {
1391+ this . loadGraphData ( gltfInfo . workflow , true , true , fileName )
1392+ } else if ( gltfInfo . prompt ) {
1393+ this . loadApiJson ( gltfInfo . prompt , fileName )
1394+ } else {
1395+ this . showErrorOnFileLoad ( file )
1396+ }
1397+ } else if (
1398+ file . type === 'application/json' ||
1399+ file . name ?. endsWith ( '.json' )
1400+ ) {
1401+ const reader = new FileReader ( )
1402+ reader . onload = async ( ) => {
1403+ const readerResult = reader . result as string
1404+ const jsonContent = JSON . parse ( readerResult )
1405+ if ( jsonContent ?. templates ) {
1406+ this . loadTemplateData ( jsonContent )
1407+ } else if ( this . isApiJson ( jsonContent ) ) {
1408+ this . loadApiJson ( jsonContent , fileName )
1409+ } else {
1410+ await this . loadGraphData (
1411+ JSON . parse ( readerResult ) ,
1412+ true ,
1413+ true ,
1414+ fileName
1415+ )
1416+ }
1417+ }
1418+ reader . readAsText ( file )
1419+ } else if (
1420+ file . name ?. endsWith ( '.latent' ) ||
1421+ file . name ?. endsWith ( '.safetensors' )
1422+ ) {
1423+ const info = await getLatentMetadata ( file )
1424+ // TODO define schema to LatentMetadata
1425+ // @ts -expect-error
1426+ if ( info . workflow ) {
1427+ await this . loadGraphData (
1428+ // @ts -expect-error
1429+ JSON . parse ( info . workflow ) ,
1430+ true ,
1431+ true ,
1432+ fileName
1433+ )
1434+ // @ts -expect-error
1435+ } else if ( info . prompt ) {
1436+ // @ts -expect-error
1437+ this . loadApiJson ( JSON . parse ( info . prompt ) )
1438+ } else {
1439+ this . showErrorOnFileLoad ( file )
1440+ }
1441+ } else {
13141442 this . showErrorOnFileLoad ( file )
13151443 }
13161444 }
0 commit comments