@imgly/plugin-autocaption-web 1.69.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +652 -0
- package/README.md +139 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/TranscriptionProvider.d.ts +34 -0
- package/dist/autocaptionService.d.ts +38 -0
- package/dist/fal-ai/ElevenLabsScribeV2.d.ts +18 -0
- package/dist/fal-ai/createFalClient.d.ts +3 -0
- package/dist/fal-ai/index.d.ts +2 -0
- package/dist/fal-ai/index.mjs +11 -0
- package/dist/fal-ai/index.mjs.map +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +15 -0
- package/dist/index.mjs.map +7 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/wordsToSrt.d.ts +24 -0
- package/package.json +73 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AutocaptionPluginConfig } from './plugin';
|
|
2
|
+
declare const Plugin: (config: AutocaptionPluginConfig) => {
|
|
3
|
+
initialize: (context: import("@cesdk/cesdk-js").EditorPluginContext) => void | Promise<void>;
|
|
4
|
+
name: string;
|
|
5
|
+
version: string;
|
|
6
|
+
};
|
|
7
|
+
export default Plugin;
|
|
8
|
+
export type { AutocaptionPluginConfig };
|
|
9
|
+
export type { TranscriptionProvider } from './TranscriptionProvider';
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
async function x(i,e,v,d){let c=d?.debug?console.log.bind(console):()=>{};try{if(i.block.getType(e)==="//ly.img.ubq/audio")c(`[autocaptionService] Loading audio resource for block ${e}...`),await i.block.forceLoadAVResource(e);else if(i.block.supportsFill(e)){let C=i.block.getFill(e);c(`[autocaptionService] Loading video resource for fill ${C}...`),await i.block.forceLoadAVResource(C)}c(`[autocaptionService] Exporting audio from block ${e}...`);let f=await i.block.exportAudio(e,{mimeType:"audio/mp4",abortSignal:d?.abortSignal});c(`[autocaptionService] Audio exported: ${f.size} bytes (${f.type})`),c(`[autocaptionService] Transcribing block ${e} via ${v.name}...`);let{srt:y}=await v.transcribe(f,{language:d?.language,maxLineLength:d?.maxLineLength,maxLines:d?.maxLines,abortSignal:d?.abortSignal,debug:d?.debug});if(!y||y.trim().length===0)return c(`[autocaptionService] No speech detected in block ${e}`),{blockId:e,status:"no_speech",captions:[]};c(`[autocaptionService] SRT received (${y.length} chars), creating caption blocks for block ${e}...`);let p=new Blob([y],{type:"text/srt"}),h=URL.createObjectURL(p);try{let C=await i.block.createCaptionsFromURI(h);return c(`[autocaptionService] Created ${C.length} caption block(s) from block ${e}`),{blockId:e,status:"success",captions:C}}finally{URL.revokeObjectURL(h)}}catch(m){return console.error(`[autocaptionService] Error processing block ${e}:`,m),{blockId:e,status:"error",error:m instanceof Error?m:new Error(String(m))}}}async function B(i,e,v,d){let c=d?.debug?console.log.bind(console):()=>{};if(c("[autocaptionService] Starting caption generation for",e.length,"block(s):",e),e.length===0)return{captions:[],blockResults:[]};let{language:m,maxLineLength:f,maxLines:y,onProgress:p,abortSignal:h,locale:C,debug:w}=d??{},S=await Promise.all(e.map(a=>x(i,a,v,{language:m,maxLineLength:f,maxLines:y,abortSignal:h,debug:w})));if(h?.aborted){for(let b of S)if(b.captions)for(let u of b.captions)i.block.isValid(u)&&i.block.destroy(u);c("[autocaptionService] Generation aborted by user");let a=new Error("Caption generation was cancelled");throw a.name="AbortError",a}let t=[];for(let a of S)a.status==="success"&&a.captions&&t.push(...a.captions);if(c(`[autocaptionService] All blocks processed, ${t.length} total caption(s)`),t.length===0)return c("[autocaptionService] No captions generated, returning empty"),p?.(1),{captions:[],blockResults:S};let o=i.scene.getCurrentPage();if(o==null)throw new Error("No current page found in the scene.");let r=i.block.getChildren(o).find(a=>i.block.getType(a)==="//ly.img.ubq/captionTrack");r!=null&&(c("[autocaptionService] Removing existing caption track:",r),i.block.destroy(r));let l=i.block.create("//ly.img.ubq/captionTrack");for(let a of t)i.block.appendChild(l,a);i.block.appendChild(o,l),await P(i,t,C);let[s]=t;return i.block.alignHorizontally([s],"Center"),i.block.alignVertically([s],"Center"),i.editor.addUndoStep(),c("[autocaptionService] Caption track created and styled, done"),p?.(1),{captions:t,blockResults:S}}async function P(i,e,v){let d=i.scene.get();if(d==null)return;let c="ly.img.caption.presets",m="ly.img.caption.presets.outline";for(let p of e)i.block.setWidthMode(p,"Percent"),i.block.setHeightMode(p,"Percent"),i.block.setWidth(p,.8),i.block.setHeight(p,.2);if(!i.asset.findAllSources().includes(c)||e.length===0)return;let y=i.block.getFloat(d,"scene/dpi");i.block.setFloat(d,"scene/dpi",300);try{let p=await i.asset.fetchAsset(c,m,{locale:v});p!=null&&await i.asset.applyToBlock(c,p,e[0])}catch(p){console.error("[autocaptionService] Failed to apply caption preset, using default styling:",p)}finally{i.block.setFloat(d,"scene/dpi",y)}}var k="@imgly/plugin-autocaption-web",L=i=>({initialize({cesdk:e}){if(!e)throw new Error("AutocaptionPlugin requires the editor (cesdk) context.");let{provider:v,debug:d=!1}=i,c=d?console.log.bind(console):()=>{};G(e),e.i18n.setTranslations({en:{"ly.img.plugin-autocaption-web.generateAutomatically":"Generate Automatically","ly.img.plugin-autocaption-web.autoGenerate.description":"Please select which media should be included for caption generation.","ly.img.plugin-autocaption-web.autoGenerate.selectAll":"Select All","ly.img.plugin-autocaption-web.autoGenerate.deselectAll":"Deselect All","ly.img.plugin-autocaption-web.autoGenerate.emptyState":"No audio or video blocks found in the current scene.","ly.img.plugin-autocaption-web.autoGenerate.sectionAudio":"Audio","ly.img.plugin-autocaption-web.autoGenerate.sectionVideo":"Video","ly.img.plugin-autocaption-web.autoGenerate.generate":"Generate Captions","ly.img.plugin-autocaption-web.autoGenerate.cancel":"Cancel","ly.img.plugin-autocaption-web.notification.allFailed":"Caption generation failed.","ly.img.plugin-autocaption-web.notification.noSpeechAll":"No speech detected in the selected media."}});let m=null;e.ui.registerComponent("ly.img.autocaption.generateButton",({builder:t})=>{t.Button("Auto Caption",{icon:"@imgly/Sparkle",color:"accent",label:"ly.img.plugin-autocaption-web.generateAutomatically",onClick:()=>{e.ui.setOrderContext({in:"ly.img.caption.panel"},{view:"auto-generate"})}})}),e.ui.insertOrderComponent({in:"ly.img.caption.panel",when:{view:"create"},before:"ly.img.caption.panel.create"},"ly.img.autocaption.generateButton");let f=(t,o)=>`${k}.selected.${o}-${t}`;e.ui.registerComponent("ly.img.autocaption.header",({builder:t,experimental:{global:o}})=>{let n=e.engine.block.findByKind("audio"),r=e.engine.block.findByKind("video");if(n.length===0&&r.length===0)return;let l=n.filter(g=>!e.engine.block.isMuted(g)),s=r.filter(g=>!p(g)),a=[...l.map(g=>o(f(g,"audio"),!0)),...s.map(g=>o(f(g,"video"),!0))],b=a.length>0&&a.every(g=>g.value),u=o(`${k}.isGenerating`,!1);t.Section("header-section",{children:()=>{t.Text("description",{content:"ly.img.plugin-autocaption-web.autoGenerate.description",align:"center"}),t.Button("selectAll",{label:b?"ly.img.plugin-autocaption-web.autoGenerate.deselectAll":"ly.img.plugin-autocaption-web.autoGenerate.selectAll",isDisabled:a.length===0||u.value,onClick:()=>{let g=!b;for(let A of a)A.setValue(g)}})}})});let y=t=>{let o=e.engine;if(!o.block.supportsFill(t))return!1;let n=o.block.getFill(t);try{return o.block.getAudioTrackCountFromVideo(n)>0}catch{return!1}},p=t=>{let o=e.engine;if(!o.block.supportsFill(t))return!1;if(!y(t))return!0;let n=o.block.getFill(t);return o.block.isMuted(n)},h=t=>{if(t)try{let r=new URL(t).pathname.split("/").pop();return r&&r.trim()!==""?r:void 0}catch{let n=t.split("/").pop();return n&&n.trim()!==""?n:void 0}},C=t=>{let o=e.engine,n=o.block.getName(t);if(n&&n.trim()!=="")return n;if(o.block.hasMetadata(t,"fallback-name")){let s=o.block.getMetadata(t,"fallback-name");if(s.trim()!=="")return s}let r=o.block.getType(t);if(r==="//ly.img.ubq/audio"){let s=o.block.getString(t,"audio/fileURI"),a=h(s);if(a)return a}else if(r==="//ly.img.ubq/graphic"&&o.block.supportsFill(t)){let s=o.block.getFill(t);if(o.block.getType(s)==="//ly.img.ubq/fill/video"){let b=o.block.getString(s,"fill/video/fileURI"),u=h(b);if(u)return u}}return`${o.block.getKind(t)} #${t}`};e.ui.registerComponent("ly.img.autocaption.emptyState",({builder:t})=>{let o=e.engine.block.findByKind("audio"),n=e.engine.block.findByKind("video");o.length===0&&n.length===0&&t.Section("empty-section",{children:()=>{t.Text("empty-message",{content:"ly.img.plugin-autocaption-web.autoGenerate.emptyState",align:"center"})}})}),e.ui.registerComponent("ly.img.autocaption.audioCheckboxes",({builder:t,experimental:{global:o}})=>{let n=e.engine.block.findByKind("audio");if(n.length===0)return;let r=o(`${k}.isGenerating`,!1);t.Section("audio-section",{title:"ly.img.plugin-autocaption-web.autoGenerate.sectionAudio",children:()=>{for(let l of n){let s=e.engine.block.isMuted(l),a=o(f(l,"audio"),!s);t.Checkbox(f(l,"audio"),{truncateLabel:!0,inputLabel:C(l),icon:s?"@imgly/VolumeMute":"@imgly/Audio",isDisabled:s||r.value,value:a.value,setValue:a.setValue})}}})}),e.ui.registerComponent("ly.img.autocaption.videoCheckboxes",({builder:t,experimental:{global:o}})=>{let n=e.engine.block.findByKind("video");if(n.length===0)return;let r=o(`${k}.isGenerating`,!1);t.Section("video-section",{title:"ly.img.plugin-autocaption-web.autoGenerate.sectionVideo",children:()=>{for(let l of n){let s=p(l),a=o(f(l,"video"),!s);t.Checkbox(f(l,"video"),{truncateLabel:!0,inputLabel:C(l),icon:s?"@imgly/VolumeMute":"@imgly/Video",isDisabled:s||r.value,value:a.value,setValue:a.setValue})}}})});let w=t=>{let o=e.engine.block.findByKind("audio"),n=e.engine.block.findByKind("video"),r=[];for(let l of o)e.engine.block.isMuted(l)||t(f(l,"audio"),!0).value&&r.push(l);for(let l of n)p(l)||t(f(l,"video"),!0).value&&r.push(l);return r},S=(t,o)=>{o.some(r=>r.status==="error")?t.ui.showNotification({type:"error",message:"ly.img.plugin-autocaption-web.notification.allFailed",duration:"long"}):t.ui.showNotification({type:"warning",message:"ly.img.plugin-autocaption-web.notification.noSpeechAll",duration:"long"})};e.ui.registerComponent("ly.img.autocaption.actions",({builder:t,experimental:{global:o}})=>{let n=e.engine.block.findByKind("audio"),r=e.engine.block.findByKind("video"),l=n.filter(u=>!e.engine.block.isMuted(u)),s=r.filter(u=>!p(u)),a=[...l.map(u=>o(f(u,"audio"),!0)),...s.map(u=>o(f(u,"video"),!0))].some(u=>u.value),b=o(`${k}.isGenerating`,!1);t.Section("generate-section",{children:()=>{t.Button("generateCaptions",{icon:"@imgly/Sparkle",color:"accent",label:"ly.img.plugin-autocaption-web.autoGenerate.generate",size:"large",isDisabled:!a||b.value,isLoading:b.value,onClick:()=>{let u=w(o);u.length!==0&&(c("[AutocaptionPlugin] Generate clicked, selected blocks:",u),b.setValue(!0),m=new AbortController,B(e.engine,u,v,{abortSignal:m.signal,debug:d}).then(g=>{c("[AutocaptionPlugin] Generation complete,",g.captions.length,"caption(s) created"),g.captions.length>0?e.ui.setOrderContext({in:"ly.img.caption.panel"},{view:"edit"}):S(e,g.blockResults)}).catch(g=>{if(g instanceof Error&&g.name==="AbortError"){c("[AutocaptionPlugin] Generation cancelled by user");return}console.error("[AutocaptionPlugin] Generation failed:",g),e.ui.showNotification({type:"error",message:"ly.img.plugin-autocaption-web.notification.allFailed",duration:"long"})}).finally(()=>{b.setValue(!1),m=null}))}}),t.Button("cancelGenerate",{label:"ly.img.plugin-autocaption-web.autoGenerate.cancel",onClick:()=>{m&&m.abort(),e.ui.setOrderContext({in:"ly.img.caption.panel"},{view:"create"})}})}})}),e.ui.setComponentOrder({in:"ly.img.caption.panel",when:{view:"auto-generate"}},["ly.img.autocaption.header","ly.img.autocaption.emptyState","ly.img.autocaption.audioCheckboxes","ly.img.autocaption.videoCheckboxes","ly.img.autocaption.actions"])}});function G(i){i.ui.addIconSet("ly.img.autocaption",`
|
|
2
|
+
<svg>
|
|
3
|
+
<symbol
|
|
4
|
+
fill="none"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
id="@imgly/Sparkle"
|
|
8
|
+
>
|
|
9
|
+
<path d="M5.35545 2.06745C5.24149 1.72556 4.7579 1.72556 4.64394 2.06745L4.05898 3.82232C4.02166 3.93429 3.9338 4.02215 3.82184 4.05948L2.06694 4.64459C1.72506 4.75858 1.72509 5.24217 2.06699 5.3561L3.82179 5.9409C3.93378 5.97822 4.02166 6.06609 4.05899 6.17808L4.64394 7.93291C4.7579 8.2748 5.24149 8.2748 5.35545 7.93291L5.9404 6.17806C5.97773 6.06608 6.06559 5.97821 6.17757 5.94089L7.93242 5.35594C8.27431 5.24198 8.27431 4.75839 7.93242 4.64442L6.17757 4.05947C6.06559 4.02215 5.97773 3.93428 5.9404 3.8223L5.35545 2.06745Z" fill="currentColor"/>
|
|
10
|
+
<path d="M17.9632 3.23614C17.8026 2.80788 17.1968 2.80788 17.0362 3.23614L16.0787 5.78951C16.0285 5.92337 15.9229 6.02899 15.789 6.07918L13.2356 7.0367C12.8074 7.19729 12.8074 7.80307 13.2356 7.96366L15.789 8.92118C15.9229 8.97138 16.0285 9.077 16.0787 9.21085L17.0362 11.7642C17.1968 12.1925 17.8026 12.1925 17.9632 11.7642L18.9207 9.21086C18.9709 9.077 19.0765 8.97138 19.2104 8.92118L21.7637 7.96366C22.192 7.80307 22.192 7.1973 21.7637 7.0367L19.2104 6.07918C19.0765 6.02899 18.9709 5.92337 18.9207 5.78951L17.9632 3.23614Z" fill="currentColor"/>
|
|
11
|
+
<path d="M9.30058 7.82012C9.54712 7.1791 10.454 7.1791 10.7006 7.82012L12.3809 12.189C12.4571 12.3871 12.6136 12.5436 12.8117 12.6198L17.1806 14.3001C17.8216 14.5466 17.8216 15.4536 17.1806 15.7001L12.8117 17.3804C12.6136 17.4566 12.4571 17.6131 12.3809 17.8112L10.7006 22.1801C10.454 22.8211 9.54712 22.8211 9.30058 22.1801L7.62024 17.8112C7.54406 17.6131 7.38754 17.4566 7.18947 17.3804L2.82061 15.7001C2.17959 15.4536 2.17959 14.5466 2.82061 14.3001L7.18947 12.6198C7.38754 12.5436 7.54406 12.3871 7.62024 12.189L9.30058 7.82012Z" fill="currentColor"/>
|
|
12
|
+
</symbol>
|
|
13
|
+
</svg>
|
|
14
|
+
`)}var T=i=>({name:k,version:"1.69.0-rc.4",...L(i)}),D=T;export{D as default};
|
|
15
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/autocaptionService.ts", "../src/plugin.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type CreativeEngine from '@cesdk/engine';\nimport type { DesignBlockId } from '@cesdk/engine';\nimport type {\n TranscriptionOptions,\n TranscriptionProvider\n} from './TranscriptionProvider';\n\nexport interface GenerateCaptionsOptions extends TranscriptionOptions {\n /** Called with overall progress 0\u20131 across all blocks. */\n onProgress?: (progress: number) => void;\n /** AbortSignal to cancel the operation. */\n abortSignal?: AbortSignal;\n /** Locale for caption preset styling (e.g. \"en\"). */\n locale?: string;\n /** Enable verbose logging to the console. */\n debug?: boolean;\n}\n\nexport interface BlockCaptionResult {\n blockId: DesignBlockId;\n status: 'success' | 'no_speech' | 'error';\n captions?: DesignBlockId[];\n error?: Error;\n}\n\nexport interface GenerateCaptionsResult {\n captions: DesignBlockId[];\n blockResults: BlockCaptionResult[];\n}\n\n/**\n * Process a single block: export audio \u2192 transcribe \u2192 create caption blocks.\n */\nasync function processBlock(\n engine: CreativeEngine,\n blockId: DesignBlockId,\n provider: TranscriptionProvider,\n options?: TranscriptionOptions & {\n abortSignal?: AbortSignal;\n debug?: boolean;\n }\n): Promise<BlockCaptionResult> {\n // eslint-disable-next-line no-console\n const log = options?.debug ? console.log.bind(console) : () => {};\n\n try {\n // 1. Force load the AV resource before exporting\n const blockType = engine.block.getType(blockId);\n if (blockType === '//ly.img.ubq/audio') {\n log(\n `[autocaptionService] Loading audio resource for block ${blockId}...`\n );\n await engine.block.forceLoadAVResource(blockId);\n } else if (engine.block.supportsFill(blockId)) {\n const fillId = engine.block.getFill(blockId);\n log(`[autocaptionService] Loading video resource for fill ${fillId}...`);\n await engine.block.forceLoadAVResource(fillId);\n }\n\n // 2. Export audio from the block\n log(`[autocaptionService] Exporting audio from block ${blockId}...`);\n const audioBlob = await engine.block.exportAudio(blockId, {\n mimeType: 'audio/mp4',\n abortSignal: options?.abortSignal\n });\n\n log(\n `[autocaptionService] Audio exported: ${audioBlob.size} bytes (${audioBlob.type})`\n );\n\n // 3. Transcribe via the provider\n log(\n `[autocaptionService] Transcribing block ${blockId} via ${provider.name}...`\n );\n const { srt } = await provider.transcribe(audioBlob, {\n language: options?.language,\n maxLineLength: options?.maxLineLength,\n maxLines: options?.maxLines,\n abortSignal: options?.abortSignal,\n debug: options?.debug\n });\n\n // 4. Check if SRT is empty (no speech detected)\n if (!srt || srt.trim().length === 0) {\n log(`[autocaptionService] No speech detected in block ${blockId}`);\n return { blockId, status: 'no_speech', captions: [] };\n }\n\n // 5. Create captions from the SRT text\n log(\n `[autocaptionService] SRT received (${srt.length} chars), creating caption blocks for block ${blockId}...`\n );\n const srtBlob = new Blob([srt], { type: 'text/srt' });\n const srtUrl = URL.createObjectURL(srtBlob);\n\n try {\n const captions = await engine.block.createCaptionsFromURI(srtUrl);\n log(\n `[autocaptionService] Created ${captions.length} caption block(s) from block ${blockId}`\n );\n return { blockId, status: 'success', captions };\n } finally {\n URL.revokeObjectURL(srtUrl);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n `[autocaptionService] Error processing block ${blockId}:`,\n error\n );\n return {\n blockId,\n status: 'error',\n error: error instanceof Error ? error : new Error(String(error))\n };\n }\n}\n\n/**\n * Orchestrates caption generation for one or more blocks.\n *\n * For each block: export audio \u2192 transcribe \u2192 create caption blocks.\n * All resulting captions are collected into a single caption track\n * on the current page.\n *\n * Blocks are processed in parallel for better performance.\n *\n * @param engine - CE.SDK CreativeEngine instance\n * @param blockIds - Design blocks to export audio from (audio or video blocks)\n * @param provider - Any TranscriptionProvider implementation\n * @param options - Language, progress, and formatting options\n */\nexport async function generateCaptions(\n engine: CreativeEngine,\n blockIds: DesignBlockId[],\n provider: TranscriptionProvider,\n options?: GenerateCaptionsOptions\n): Promise<GenerateCaptionsResult> {\n // eslint-disable-next-line no-console\n const log = options?.debug ? console.log.bind(console) : () => {};\n\n log(\n '[autocaptionService] Starting caption generation for',\n blockIds.length,\n 'block(s):',\n blockIds\n );\n\n if (blockIds.length === 0) {\n return { captions: [], blockResults: [] };\n }\n\n const {\n language,\n maxLineLength,\n maxLines,\n onProgress,\n abortSignal,\n locale,\n debug\n } = options ?? {};\n\n // Process all blocks in parallel\n const blockResults = await Promise.all(\n blockIds.map((blockId) =>\n processBlock(engine, blockId, provider, {\n language,\n maxLineLength,\n maxLines,\n abortSignal,\n debug\n })\n )\n );\n\n // Check if operation was aborted\n if (abortSignal?.aborted) {\n // Clean up any caption blocks that were created\n for (const result of blockResults) {\n if (result.captions) {\n for (const caption of result.captions) {\n if (engine.block.isValid(caption)) {\n engine.block.destroy(caption);\n }\n }\n }\n }\n log('[autocaptionService] Generation aborted by user');\n const abortError = new Error('Caption generation was cancelled');\n abortError.name = 'AbortError';\n throw abortError;\n }\n\n // Collect all successful captions\n const allCaptions: DesignBlockId[] = [];\n for (const result of blockResults) {\n if (result.status === 'success' && result.captions) {\n allCaptions.push(...result.captions);\n }\n }\n\n log(\n `[autocaptionService] All blocks processed, ${allCaptions.length} total caption(s)`\n );\n\n if (allCaptions.length === 0) {\n log('[autocaptionService] No captions generated, returning empty');\n onProgress?.(1);\n return { captions: [], blockResults };\n }\n\n // 5. Find current page and manage caption track\n const currentPage = engine.scene.getCurrentPage();\n if (currentPage == null) {\n throw new Error('No current page found in the scene.');\n }\n\n // Remove existing caption track if present\n const pageChildren = engine.block.getChildren(currentPage);\n const existingCaptionTrack = pageChildren.find(\n (child) => engine.block.getType(child) === '//ly.img.ubq/captionTrack'\n );\n if (existingCaptionTrack != null) {\n log(\n '[autocaptionService] Removing existing caption track:',\n existingCaptionTrack\n );\n engine.block.destroy(existingCaptionTrack);\n }\n\n // 6. Create new caption track and append all captions\n const captionTrack = engine.block.create('//ly.img.ubq/captionTrack');\n for (const caption of allCaptions) {\n engine.block.appendChild(captionTrack, caption);\n }\n engine.block.appendChild(currentPage, captionTrack);\n\n // 7. Apply default styling\n await applyDefaultCaptionStyling(engine, allCaptions, locale);\n\n // 8. Align first caption\n const [firstCaption] = allCaptions;\n engine.block.alignHorizontally([firstCaption], 'Center');\n engine.block.alignVertically([firstCaption], 'Center');\n\n // 9. Create a single undo step so the entire generation can be reverted at once\n engine.editor.addUndoStep();\n\n log('[autocaptionService] Caption track created and styled, done');\n onProgress?.(1);\n return { captions: allCaptions, blockResults };\n}\n\n/**\n * Applies default caption preset styling to all caption blocks.\n * Mirrors the logic from CaptionPanel/utils.ts setDefaultStyling.\n */\nasync function applyDefaultCaptionStyling(\n engine: CreativeEngine,\n captions: DesignBlockId[],\n locale?: string\n): Promise<void> {\n const scene = engine.scene.get();\n if (scene == null) return;\n\n const CAPTION_PRESETS_SOURCE = 'ly.img.caption.presets';\n const CAPTION_PRESETS_OUTLINE = 'ly.img.caption.presets.outline';\n\n for (const caption of captions) {\n engine.block.setWidthMode(caption, 'Percent');\n engine.block.setHeightMode(caption, 'Percent');\n engine.block.setWidth(caption, 0.8);\n engine.block.setHeight(caption, 0.2);\n }\n\n // The caption presets asset source may not be registered if the editor\n // does not include the CaptionPresetsAssetSource plugin.\n const availableSources = engine.asset.findAllSources();\n if (!availableSources.includes(CAPTION_PRESETS_SOURCE)) {\n return;\n }\n\n if (captions.length === 0) return;\n\n const dpi = engine.block.getFloat(scene, 'scene/dpi');\n engine.block.setFloat(scene, 'scene/dpi', 300);\n\n try {\n const result = await engine.asset.fetchAsset(\n CAPTION_PRESETS_SOURCE,\n CAPTION_PRESETS_OUTLINE,\n { locale }\n );\n\n if (result != null) {\n await engine.asset.applyToBlock(\n CAPTION_PRESETS_SOURCE,\n result,\n captions[0]\n );\n }\n } catch (error) {\n // Gracefully fall back to the basic width/height styling applied above.\n // The preset may fail to load (e.g. asset source not registered or network\n // error). This is non-fatal \u2014 captions still work without preset styling.\n // eslint-disable-next-line no-console\n console.error(\n '[autocaptionService] Failed to apply caption preset, using default styling:',\n error\n );\n } finally {\n engine.block.setFloat(scene, 'scene/dpi', dpi);\n }\n}\n", "import type CreativeEditorSDK from '@cesdk/cesdk-js';\nimport type { EditorPlugin } from '@cesdk/cesdk-js';\nimport {\n generateCaptions,\n type BlockCaptionResult\n} from './autocaptionService';\nimport type { TranscriptionProvider } from './TranscriptionProvider';\n\nexport interface AutocaptionPluginConfig {\n provider: TranscriptionProvider;\n /** Enable verbose logging to the console. Defaults to false. */\n debug?: boolean;\n}\n\nexport const PLUGIN_ID = '@imgly/plugin-autocaption-web';\n\nexport default (\n config: AutocaptionPluginConfig\n): Omit<EditorPlugin, 'name' | 'version'> => {\n return {\n initialize({ cesdk }) {\n if (!cesdk) {\n throw new Error(\n 'AutocaptionPlugin requires the editor (cesdk) context.'\n );\n }\n\n const { provider, debug = false } = config;\n // eslint-disable-next-line no-console\n const log = debug ? console.log.bind(console) : () => {};\n\n addIconSet(cesdk);\n\n cesdk.i18n.setTranslations({\n en: {\n 'ly.img.plugin-autocaption-web.generateAutomatically':\n 'Generate Automatically',\n 'ly.img.plugin-autocaption-web.autoGenerate.description':\n 'Please select which media should be included for caption generation.',\n 'ly.img.plugin-autocaption-web.autoGenerate.selectAll': 'Select All',\n 'ly.img.plugin-autocaption-web.autoGenerate.deselectAll':\n 'Deselect All',\n 'ly.img.plugin-autocaption-web.autoGenerate.emptyState':\n 'No audio or video blocks found in the current scene.',\n 'ly.img.plugin-autocaption-web.autoGenerate.sectionAudio': 'Audio',\n 'ly.img.plugin-autocaption-web.autoGenerate.sectionVideo': 'Video',\n 'ly.img.plugin-autocaption-web.autoGenerate.generate':\n 'Generate Captions',\n 'ly.img.plugin-autocaption-web.autoGenerate.cancel': 'Cancel',\n 'ly.img.plugin-autocaption-web.notification.allFailed':\n 'Caption generation failed.',\n 'ly.img.plugin-autocaption-web.notification.noSpeechAll':\n 'No speech detected in the selected media.'\n }\n });\n\n // AbortController for cancelling generation in progress\n let generationAbortController: AbortController | null = null;\n\n // Register the button that triggers the auto-generate view\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.generateButton',\n ({ builder }) => {\n builder.Button('Auto Caption', {\n icon: '@imgly/Sparkle',\n color: 'accent',\n label: 'ly.img.plugin-autocaption-web.generateAutomatically',\n onClick: () => {\n cesdk.ui.setOrderContext(\n { in: 'ly.img.caption.panel' },\n { view: 'auto-generate' }\n );\n }\n });\n }\n );\n\n // Insert the button into the caption panel's create view\n cesdk.ui.insertOrderComponent(\n {\n in: 'ly.img.caption.panel',\n when: { view: 'create' },\n before: 'ly.img.caption.panel.create'\n },\n 'ly.img.autocaption.generateButton'\n );\n\n const selectionKey = (blockId: number, kind: 'audio' | 'video') =>\n `${PLUGIN_ID}.selected.${kind}-${blockId}`;\n\n // Auto-generate view: Header section with description and action buttons\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.header',\n ({ builder, experimental: { global } }) => {\n const audioBlocks = cesdk.engine.block.findByKind('audio');\n const videoBlocks = cesdk.engine.block.findByKind('video');\n\n if (audioBlocks.length === 0 && videoBlocks.length === 0) {\n return;\n }\n\n // Only include non-muted blocks in the select all logic\n const selectableAudioBlocks = audioBlocks.filter(\n (id) => !cesdk.engine.block.isMuted(id)\n );\n const selectableVideoBlocks = videoBlocks.filter(\n (id) => !isVideoBlockMuted(id)\n );\n\n const entries = [\n ...selectableAudioBlocks.map((id) =>\n global(selectionKey(id, 'audio'), true)\n ),\n ...selectableVideoBlocks.map((id) =>\n global(selectionKey(id, 'video'), true)\n )\n ];\n const allSelected =\n entries.length > 0 && entries.every((e) => e.value);\n\n const isGeneratingState = global(`${PLUGIN_ID}.isGenerating`, false);\n\n builder.Section('header-section', {\n children: () => {\n builder.Text('description', {\n content:\n 'ly.img.plugin-autocaption-web.autoGenerate.description',\n align: 'center'\n });\n builder.Button('selectAll', {\n label: allSelected\n ? 'ly.img.plugin-autocaption-web.autoGenerate.deselectAll'\n : 'ly.img.plugin-autocaption-web.autoGenerate.selectAll',\n isDisabled: entries.length === 0 || isGeneratingState.value,\n onClick: () => {\n const newValue = !allSelected;\n for (const entry of entries) {\n entry.setValue(newValue);\n }\n }\n });\n }\n });\n }\n );\n\n const videoBlockHasAudio = (blockId: number): boolean => {\n const engine = cesdk.engine;\n if (!engine.block.supportsFill(blockId)) return false;\n const fillId = engine.block.getFill(blockId);\n try {\n return engine.block.getAudioTrackCountFromVideo(fillId) > 0;\n } catch {\n return false;\n }\n };\n\n const isVideoBlockMuted = (blockId: number): boolean => {\n const engine = cesdk.engine;\n if (!engine.block.supportsFill(blockId)) return false;\n if (!videoBlockHasAudio(blockId)) return true;\n const fillId = engine.block.getFill(blockId);\n return engine.block.isMuted(fillId);\n };\n\n const getFilenameFromUri = (uri: string): string | undefined => {\n if (!uri) return undefined;\n try {\n const url = new URL(uri);\n const pathname = url.pathname;\n const filename = pathname.split('/').pop();\n return filename && filename.trim() !== '' ? filename : undefined;\n } catch {\n const parts = uri.split('/');\n const filename = parts.pop();\n return filename && filename.trim() !== '' ? filename : undefined;\n }\n };\n\n const getBlockLabel = (blockId: number): string => {\n const engine = cesdk.engine;\n\n const name = engine.block.getName(blockId);\n if (name && name.trim() !== '') {\n return name;\n }\n\n // 'fallback-name' is a CE.SDK editor convention used as a display\n // name when no explicit block name is set (see generateBlockName.ts).\n if (engine.block.hasMetadata(blockId, 'fallback-name')) {\n const fallbackName = engine.block.getMetadata(\n blockId,\n 'fallback-name'\n );\n if (fallbackName.trim() !== '') {\n return fallbackName;\n }\n }\n\n const blockType = engine.block.getType(blockId);\n\n if (blockType === '//ly.img.ubq/audio') {\n const audioUri = engine.block.getString(blockId, 'audio/fileURI');\n const filename = getFilenameFromUri(audioUri);\n if (filename) {\n return filename;\n }\n } else if (\n blockType === '//ly.img.ubq/graphic' &&\n engine.block.supportsFill(blockId)\n ) {\n const fillId = engine.block.getFill(blockId);\n const fillType = engine.block.getType(fillId);\n if (fillType === '//ly.img.ubq/fill/video') {\n const videoUri = engine.block.getString(\n fillId,\n 'fill/video/fileURI'\n );\n const filename = getFilenameFromUri(videoUri);\n if (filename) {\n return filename;\n }\n }\n }\n\n const kind = engine.block.getKind(blockId);\n return `${kind} #${blockId}`;\n };\n\n // Auto-generate view: Empty state section (no audio/video found)\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.emptyState',\n ({ builder }) => {\n const audioBlocks = cesdk.engine.block.findByKind('audio');\n const videoBlocks = cesdk.engine.block.findByKind('video');\n\n if (audioBlocks.length === 0 && videoBlocks.length === 0) {\n builder.Section('empty-section', {\n children: () => {\n builder.Text('empty-message', {\n content:\n 'ly.img.plugin-autocaption-web.autoGenerate.emptyState',\n align: 'center'\n });\n }\n });\n }\n }\n );\n\n // Auto-generate view: Audio checkboxes section\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.audioCheckboxes',\n ({ builder, experimental: { global } }) => {\n const audioBlocks = cesdk.engine.block.findByKind('audio');\n\n if (audioBlocks.length === 0) {\n return;\n }\n\n const isGeneratingState = global(`${PLUGIN_ID}.isGenerating`, false);\n\n builder.Section('audio-section', {\n title: 'ly.img.plugin-autocaption-web.autoGenerate.sectionAudio',\n children: () => {\n for (const blockId of audioBlocks) {\n const isMuted = cesdk.engine.block.isMuted(blockId);\n const blockState = global(\n selectionKey(blockId, 'audio'),\n !isMuted\n );\n builder.Checkbox(selectionKey(blockId, 'audio'), {\n truncateLabel: true,\n inputLabel: getBlockLabel(blockId),\n icon: isMuted ? '@imgly/VolumeMute' : '@imgly/Audio',\n isDisabled: isMuted || isGeneratingState.value,\n value: blockState.value,\n setValue: blockState.setValue\n });\n }\n }\n });\n }\n );\n\n // Auto-generate view: Video checkboxes section\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.videoCheckboxes',\n ({ builder, experimental: { global } }) => {\n const videoBlocks = cesdk.engine.block.findByKind('video');\n\n if (videoBlocks.length === 0) {\n return;\n }\n\n const isGeneratingState = global(`${PLUGIN_ID}.isGenerating`, false);\n\n builder.Section('video-section', {\n title: 'ly.img.plugin-autocaption-web.autoGenerate.sectionVideo',\n children: () => {\n for (const blockId of videoBlocks) {\n const isMuted = isVideoBlockMuted(blockId);\n const blockState = global(\n selectionKey(blockId, 'video'),\n !isMuted\n );\n builder.Checkbox(selectionKey(blockId, 'video'), {\n truncateLabel: true,\n inputLabel: getBlockLabel(blockId),\n icon: isMuted ? '@imgly/VolumeMute' : '@imgly/Video',\n isDisabled: isMuted || isGeneratingState.value,\n value: blockState.value,\n setValue: blockState.setValue\n });\n }\n }\n });\n }\n );\n\n const getSelectedBlockIds = (\n globalFn: (key: string, defaultValue: boolean) => { value: boolean }\n ): number[] => {\n const audioBlocks = cesdk.engine.block.findByKind('audio');\n const videoBlocks = cesdk.engine.block.findByKind('video');\n const selected: number[] = [];\n\n for (const id of audioBlocks) {\n if (cesdk.engine.block.isMuted(id)) continue;\n if (globalFn(selectionKey(id, 'audio'), true).value) {\n selected.push(id);\n }\n }\n for (const id of videoBlocks) {\n if (isVideoBlockMuted(id)) continue;\n if (globalFn(selectionKey(id, 'video'), true).value) {\n selected.push(id);\n }\n }\n return selected;\n };\n\n const showResultNotifications = (\n sdk: CreativeEditorSDK,\n blockResults: BlockCaptionResult[]\n ) => {\n const hasErrors = blockResults.some((r) => r.status === 'error');\n\n if (hasErrors) {\n sdk.ui.showNotification({\n type: 'error',\n message: 'ly.img.plugin-autocaption-web.notification.allFailed',\n duration: 'long'\n });\n } else {\n sdk.ui.showNotification({\n type: 'warning',\n message: 'ly.img.plugin-autocaption-web.notification.noSpeechAll',\n duration: 'long'\n });\n }\n };\n\n // Auto-generate view: Generate and Cancel buttons section\n cesdk.ui.registerComponent(\n 'ly.img.autocaption.actions',\n ({ builder, experimental: { global } }) => {\n const audioBlocks = cesdk.engine.block.findByKind('audio');\n const videoBlocks = cesdk.engine.block.findByKind('video');\n\n // Only consider non-muted blocks for selection state\n const selectableAudioBlocks = audioBlocks.filter(\n (id) => !cesdk.engine.block.isMuted(id)\n );\n const selectableVideoBlocks = videoBlocks.filter(\n (id) => !isVideoBlockMuted(id)\n );\n\n const hasAnySelected = [\n ...selectableAudioBlocks.map((id) =>\n global(selectionKey(id, 'audio'), true)\n ),\n ...selectableVideoBlocks.map((id) =>\n global(selectionKey(id, 'video'), true)\n )\n ].some((e) => e.value);\n\n const isGeneratingState = global(`${PLUGIN_ID}.isGenerating`, false);\n\n builder.Section('generate-section', {\n children: () => {\n builder.Button('generateCaptions', {\n icon: '@imgly/Sparkle',\n color: 'accent',\n label: 'ly.img.plugin-autocaption-web.autoGenerate.generate',\n size: 'large',\n isDisabled: !hasAnySelected || isGeneratingState.value,\n isLoading: isGeneratingState.value,\n onClick: () => {\n const blockIds = getSelectedBlockIds(global);\n if (blockIds.length === 0) return;\n\n log(\n '[AutocaptionPlugin] Generate clicked, selected blocks:',\n blockIds\n );\n isGeneratingState.setValue(true);\n generationAbortController = new AbortController();\n\n void generateCaptions(cesdk.engine, blockIds, provider, {\n abortSignal: generationAbortController.signal,\n debug\n })\n .then((result) => {\n log(\n '[AutocaptionPlugin] Generation complete,',\n result.captions.length,\n 'caption(s) created'\n );\n\n if (result.captions.length > 0) {\n cesdk.ui.setOrderContext(\n { in: 'ly.img.caption.panel' },\n { view: 'edit' }\n );\n } else {\n showResultNotifications(cesdk, result.blockResults);\n }\n })\n .catch((error) => {\n if (\n error instanceof Error &&\n error.name === 'AbortError'\n ) {\n log('[AutocaptionPlugin] Generation cancelled by user');\n return;\n }\n // eslint-disable-next-line no-console\n console.error(\n '[AutocaptionPlugin] Generation failed:',\n error\n );\n cesdk.ui.showNotification({\n type: 'error',\n message:\n 'ly.img.plugin-autocaption-web.notification.allFailed',\n duration: 'long'\n });\n })\n .finally(() => {\n isGeneratingState.setValue(false);\n generationAbortController = null;\n });\n }\n });\n builder.Button('cancelGenerate', {\n label: 'ly.img.plugin-autocaption-web.autoGenerate.cancel',\n onClick: () => {\n if (generationAbortController) {\n generationAbortController.abort();\n }\n cesdk.ui.setOrderContext(\n { in: 'ly.img.caption.panel' },\n { view: 'create' }\n );\n }\n });\n }\n });\n }\n );\n\n // Set the component order for the auto-generate view\n cesdk.ui.setComponentOrder(\n { in: 'ly.img.caption.panel', when: { view: 'auto-generate' } },\n [\n 'ly.img.autocaption.header',\n 'ly.img.autocaption.emptyState',\n 'ly.img.autocaption.audioCheckboxes',\n 'ly.img.autocaption.videoCheckboxes',\n 'ly.img.autocaption.actions'\n ]\n );\n }\n };\n};\n\nfunction addIconSet(cesdk: CreativeEditorSDK) {\n cesdk.ui.addIconSet(\n 'ly.img.autocaption',\n `\n <svg>\n <symbol\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n id=\"@imgly/Sparkle\"\n >\n <path d=\"M5.35545 2.06745C5.24149 1.72556 4.7579 1.72556 4.64394 2.06745L4.05898 3.82232C4.02166 3.93429 3.9338 4.02215 3.82184 4.05948L2.06694 4.64459C1.72506 4.75858 1.72509 5.24217 2.06699 5.3561L3.82179 5.9409C3.93378 5.97822 4.02166 6.06609 4.05899 6.17808L4.64394 7.93291C4.7579 8.2748 5.24149 8.2748 5.35545 7.93291L5.9404 6.17806C5.97773 6.06608 6.06559 5.97821 6.17757 5.94089L7.93242 5.35594C8.27431 5.24198 8.27431 4.75839 7.93242 4.64442L6.17757 4.05947C6.06559 4.02215 5.97773 3.93428 5.9404 3.8223L5.35545 2.06745Z\" fill=\"currentColor\"/>\n<path d=\"M17.9632 3.23614C17.8026 2.80788 17.1968 2.80788 17.0362 3.23614L16.0787 5.78951C16.0285 5.92337 15.9229 6.02899 15.789 6.07918L13.2356 7.0367C12.8074 7.19729 12.8074 7.80307 13.2356 7.96366L15.789 8.92118C15.9229 8.97138 16.0285 9.077 16.0787 9.21085L17.0362 11.7642C17.1968 12.1925 17.8026 12.1925 17.9632 11.7642L18.9207 9.21086C18.9709 9.077 19.0765 8.97138 19.2104 8.92118L21.7637 7.96366C22.192 7.80307 22.192 7.1973 21.7637 7.0367L19.2104 6.07918C19.0765 6.02899 18.9709 5.92337 18.9207 5.78951L17.9632 3.23614Z\" fill=\"currentColor\"/>\n<path d=\"M9.30058 7.82012C9.54712 7.1791 10.454 7.1791 10.7006 7.82012L12.3809 12.189C12.4571 12.3871 12.6136 12.5436 12.8117 12.6198L17.1806 14.3001C17.8216 14.5466 17.8216 15.4536 17.1806 15.7001L12.8117 17.3804C12.6136 17.4566 12.4571 17.6131 12.3809 17.8112L10.7006 22.1801C10.454 22.8211 9.54712 22.8211 9.30058 22.1801L7.62024 17.8112C7.54406 17.6131 7.38754 17.4566 7.18947 17.3804L2.82061 15.7001C2.17959 15.4536 2.17959 14.5466 2.82061 14.3001L7.18947 12.6198C7.38754 12.5436 7.54406 12.3871 7.62024 12.189L9.30058 7.82012Z\" fill=\"currentColor\"/>\n </symbol>\n </svg>\n`\n );\n}\n", "import plugin, { PLUGIN_ID } from './plugin';\nimport type { AutocaptionPluginConfig } from './plugin';\n\nconst Plugin = (config: AutocaptionPluginConfig) => ({\n name: PLUGIN_ID,\n version: PLUGIN_VERSION,\n ...plugin(config)\n});\n\nexport default Plugin;\nexport type { AutocaptionPluginConfig };\nexport type { TranscriptionProvider } from './TranscriptionProvider';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["processBlock", "engine", "blockId", "provider", "options", "log", "fillId", "audioBlob", "srt", "srtBlob", "srtUrl", "captions", "error", "generateCaptions", "blockIds", "language", "maxLineLength", "maxLines", "onProgress", "abortSignal", "locale", "debug", "blockResults", "result", "caption", "abortError", "allCaptions", "currentPage", "existingCaptionTrack", "child", "captionTrack", "applyDefaultCaptionStyling", "firstCaption", "scene", "CAPTION_PRESETS_SOURCE", "CAPTION_PRESETS_OUTLINE", "dpi", "PLUGIN_ID", "plugin_default", "config", "cesdk", "provider", "debug", "log", "addIconSet", "generationAbortController", "builder", "selectionKey", "blockId", "kind", "global", "audioBlocks", "videoBlocks", "selectableAudioBlocks", "id", "selectableVideoBlocks", "isVideoBlockMuted", "entries", "allSelected", "e", "isGeneratingState", "newValue", "entry", "videoBlockHasAudio", "engine", "fillId", "getFilenameFromUri", "uri", "filename", "getBlockLabel", "name", "fallbackName", "blockType", "audioUri", "videoUri", "isMuted", "blockState", "getSelectedBlockIds", "globalFn", "selected", "showResultNotifications", "sdk", "blockResults", "hasAnySelected", "blockIds", "generateCaptions", "result", "error", "Plugin", "config", "PLUGIN_ID", "plugin_default", "src_default"]
|
|
7
|
+
}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EditorPlugin } from '@cesdk/cesdk-js';
|
|
2
|
+
import type { TranscriptionProvider } from './TranscriptionProvider';
|
|
3
|
+
export interface AutocaptionPluginConfig {
|
|
4
|
+
provider: TranscriptionProvider;
|
|
5
|
+
/** Enable verbose logging to the console. Defaults to false. */
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const PLUGIN_ID = "@imgly/plugin-autocaption-web";
|
|
9
|
+
declare const _default: (config: AutocaptionPluginConfig) => Omit<EditorPlugin, "name" | "version">;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single word with timing information, as returned by ElevenLabs-style
|
|
3
|
+
* speech-to-text APIs (both via fal.ai and the direct ElevenLabs API).
|
|
4
|
+
*/
|
|
5
|
+
export interface TimedWord {
|
|
6
|
+
text: string;
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
type: 'word' | 'spacing' | 'audio_event';
|
|
10
|
+
}
|
|
11
|
+
interface WordsToSrtOptions {
|
|
12
|
+
/** Max characters per SRT line (default: 37) */
|
|
13
|
+
maxLineLength?: number;
|
|
14
|
+
/** Max lines per SRT cue (default: 2) */
|
|
15
|
+
maxLines?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Converts an array of timed words into an SRT-formatted string.
|
|
19
|
+
*
|
|
20
|
+
* Groups words into cues respecting maxLineLength and maxLines constraints,
|
|
21
|
+
* using the first word's start and last word's end as the cue timestamps.
|
|
22
|
+
*/
|
|
23
|
+
export declare function wordsToSrt(words: TimedWord[], options?: WordsToSrtOptions): string;
|
|
24
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@imgly/plugin-autocaption-web",
|
|
3
|
+
"version": "1.69.0-rc.4",
|
|
4
|
+
"description": "Autocaption plugin for the CE.SDK editor",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"CE.SDK",
|
|
7
|
+
"plugin",
|
|
8
|
+
"autocaption",
|
|
9
|
+
"captions",
|
|
10
|
+
"subtitles"
|
|
11
|
+
],
|
|
12
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "IMG.LY GmbH",
|
|
15
|
+
"email": "support@img.ly",
|
|
16
|
+
"url": "https://img.ly"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"email": "support@img.ly"
|
|
20
|
+
},
|
|
21
|
+
"source": "./src/index.ts",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": "./dist/index.mjs",
|
|
27
|
+
"types": "./dist/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./fal-ai": {
|
|
30
|
+
"import": "./dist/fal-ai/index.mjs",
|
|
31
|
+
"types": "./dist/fal-ai/index.d.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://img.ly/docs/cesdk/",
|
|
35
|
+
"files": [
|
|
36
|
+
"LICENSE.md",
|
|
37
|
+
"README.md",
|
|
38
|
+
"dist/"
|
|
39
|
+
],
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@fal-ai/client": "^1.9.0",
|
|
42
|
+
"@types/jest": "^30.0.0",
|
|
43
|
+
"chalk": "^5.4.1",
|
|
44
|
+
"concurrently": "^8.2.2",
|
|
45
|
+
"esbuild": "^0.19.12",
|
|
46
|
+
"eslint": "^8.57.1",
|
|
47
|
+
"jest": "^29.7.0",
|
|
48
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
49
|
+
"ts-jest": "^29.1.2",
|
|
50
|
+
"ts-node": "^10.9.2",
|
|
51
|
+
"typescript": "^5.7.3"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@cesdk/cesdk-js": "1.69.0-rc.4"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"start": "pnpm run watch",
|
|
58
|
+
"clean": "pnpm exec rimraf dist",
|
|
59
|
+
"purge": "pnpm exec rimraf node_modules",
|
|
60
|
+
"build": "pnpm run clean && pnpm exec node scripts/build.mjs",
|
|
61
|
+
"dev": "SKIP_DTS=true node scripts/watch.mjs",
|
|
62
|
+
"dev:wait": "node ../../scripts/dev-wait.mjs",
|
|
63
|
+
"dev:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput",
|
|
64
|
+
"check:all": "concurrently -n lint,type,pretty \"pnpm run check:lint\" \"pnpm run check:types\" \"pnpm run check:pretty\"",
|
|
65
|
+
"check:lint": "eslint --max-warnings 0 --ignore-pattern '**/__tests__/**' --ignore-pattern '**/*.test.ts' './src/**/*.{ts,tsx}'",
|
|
66
|
+
"check:pretty": "prettier --list-different './src/**/*.{ts,tsx}'",
|
|
67
|
+
"test": "jest",
|
|
68
|
+
"test:watch": "jest --watch",
|
|
69
|
+
"test:coverage": "jest --coverage",
|
|
70
|
+
"check:types": "tsc --noEmit",
|
|
71
|
+
"types:create": "tsc --emitDeclarationOnly"
|
|
72
|
+
}
|
|
73
|
+
}
|