1"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1263],{876:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>b});var r=n(2784);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var u=r.createContext({}),p=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},s=function(e){var t=p(e.components);return r.createElement(u.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},c=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,u=e.parentName,s=o(e,["components","mdxType","originalType","parentName"]),m=p(n),c=i,b=m["".concat(u,".").concat(c)]||m[c]||d[c]||a;return n?r.createElement(b,l(l({ref:t},s),{},{components:n})):r.createElement(b,l({ref:t},s))}));function b(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,l=new Array(a);l[0]=c;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o[m]="string"==typeof e?e:i,l[1]=o;for(var p=2;p<a;p++)l[p]=n[p];return r.createElement.apply(null,l)}return r.createElement.apply(null,n)}c.displayName="MDXCreateElement"},2144:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>p});var r=n(7896),i=(n(2784),n(876));const a={},l="@ffmpeg/core",o={unversionedId:"contribution/core",id:"contribution/core",title:"@ffmpeg/core",description:"To build @ffmpeg/core, make sure your docker is version 23.0+ as",source:"@site/docs/contribution/core.md",sourceDirName:"contribution",slug:"/contribution/core",permalink:"/docs/contribution/core",draft:!1,editUrl:"https://github.com/ffmpegwasm/ffmpeg.wasm/tree/main/apps/website/docs/contribution/core.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"@ffmpeg/util",permalink:"/docs/api/util/"},next:{title:"@ffmpeg/ffmpeg",permalink:"/docs/contribution/ffmpeg"}},u={},p=[{value:"Build",id:"build",level:2},{value:"Custom Build / Reduce Build Size",id:"custom-build--reduce-build-size",level:2},{value:"Step-by-Step Example: Removing WebP Support",id:"step-by-step-example-removing-webp-support",level:3},{value:"1. Remove the library builder stage",id:"1-remove-the-library-builder-stage",level:4},{value:"2. Remove the COPY instruction",id:"2-remove-the-copy-instruction",level:4},{value:"3. Remove the configure flag",id:"3-remove-the-configure-flag",level:4},{value:"4. Remove the linker flags",id:"4-remove-the-linker-flags",level:4},{value:"5. Build and test",id:"5-build-and-test",level:4},{value:"More Advance Customization Example: Creating a Minimal Build",id:"more-advance-customization-example-creating-a-minimal-build",level:3},{value:"Publish",id:"publish",level:2}],s={toc:p},m="wrapper";function d({components:e,...t}){return(0,i.kt)(m,(0,r.Z)({},s,t,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ffmpegcore"},"@ffmpeg/core"),(0,i.kt)("p",null,"To build @ffmpeg/core, make sure your docker is version 23.0+ as\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.docker.com/build/architecture/"},"buildx")," is adopted. Also\nYou will need to install ",(0,i.kt)("inlineCode",{parentName:"p"},"make")," to run build scripts."),(0,i.kt)("h2",{id:"build"},"Build"),(0,i.kt)("p",null,"Dev Build (single thread):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ make dev\n")),(0,i.kt)("p",null,"Dev Build (multithread):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ make dev-mt\n")),(0,i.kt)("p",null,"Prodution Build (single thread):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ make prd\n")),(0,i.kt)("p",null,"Prodution Build (multithread):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ make prd-mt\n")),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"Each build might take around 1 hour depends on the spec of your machine,\nsubsequent builds are faster as most layers are cached.")),(0,i.kt)("p",null,"The output file locates at ",(0,i.kt)("strong",{parentName:"p"},"/packages/core")," or ",(0,i.kt)("strong",{parentName:"p"},"/packages/core-mt"),"."),(0,i.kt)("h2",{id:"custom-build--reduce-build-size"},"Custom Build / Reduce Build Size"),(0,i.kt)("p",null,"You can customize your build to include only the libraries you need, which can significantly reduce the final build size. This is done by modifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"Dockerfile"),"."),(0,i.kt)("hr",null),(0,i.kt)("h3",{id:"step-by-step-example-removing-webp-support"},"Step-by-Step Example: Removing WebP Support"),(0,i.kt)("p",null,"Here's how to remove ",(0,i.kt)("inlineCode",{parentName:"p"},"libwebp")," (WebP image support) from the build. The same principle applies to other libraries."),(0,i.kt)("p",null,"You need to make changes in ",(0,i.kt)("strong",{parentName:"p"},"4 places")," in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Dockerfile"),":"),(0,i.kt)("h4",{id:"1-remove-the-library-builder-stage"},"1. Remove the library builder stage"),(0,i.kt)("p",null,"Find the stage that builds the library you want to remove and delete the entire block:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-dockerfile"},"# Remove this entire block\nFROM emsdk-base AS libwebp-builder\nCOPY --from=zlib-builder $INSTALL_DIR $INSTALL_DIR\nENV LIBWEBP_BRANCH=v1.3.2\nADD https://github.com/ffmpegwasm/libwebp.git#$LIBWEBP_BRANCH /src\nCOPY build/libwebp.sh /src/build.sh\nRUN bas
1h -x /src/build.sh\n")),(0,i.kt)("h4",{id:"2-remove-the-copy-instruction"},"2. Remove the COPY instruction"),(0,i.kt)("p",null,"In the ",(0,i.kt)("inlineCode",{parentName:"p"},"ffmpeg-base")," stage, remove the line that copies the built library:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-dockerfile"},"# Remove this line\nCOPY --from=libwebp-builder $INSTALL_DIR $INSTALL_DIR\n")),(0,i.kt)("h4",{id:"3-remove-the-configure-flag"},"3. Remove the configure flag"),(0,i.kt)("p",null,"In the ",(0,i.kt)("inlineCode",{parentName:"p"},"ffmpeg-builder")," stage, remove the corresponding ",(0,i.kt)("inlineCode",{parentName:"p"},"--enable-lib...")," flag:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-dockerfile"},"# Remove this line from the ffmpeg-builder stage\n--enable-libwebp \\\n")),(0,i.kt)("h4",{id:"4-remove-the-linker-flags"},"4. Remove the linker flags"),(0,i.kt)("p",null,"In the ",(0,i.kt)("inlineCode",{parentName:"p"},"ffmpeg-wasm-builder")," stage, remove the library from ",(0,i.kt)("inlineCode",{parentName:"p"},"FFMPEG_LIBS"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-dockerfile"},"# Remove these lines from FFMPEG_LIBS\n-lwebpmux \\\n-lwebp \\\n-lsharpyuv \\\n")),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},(0,i.kt)("strong",{parentName:"p"},"\ud83d\udca1 Pro Tip:")," Start by removing just the main library flag (e.g., ",(0,i.kt)("inlineCode",{parentName:"p"},"-lwebp"),'). If the build fails with "undefined reference" errors, those errors will tell you exactly which additional libraries to remove.')),(0,i.kt)("h4",{id:"5-build-and-test"},"5. Build and test"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"# Run the build command\nmake prd\n\n# Output will be in packages/core/dist/\n")),(0,i.kt)("hr",null),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Additional Build Size Optimization:")),(0,i.kt)("p",null,"You can sometimes play around with ",(0,i.kt)("inlineCode",{parentName:"p"},"build/ffmpeg-wasm.sh")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"build/ffmpeg.sh")," to disable things you are not using to make the size smaller."),(0,i.kt)("h3",{id:"more-advance-customization-example-creating-a-minimal-build"},"More Advance Customization Example: Creating a Minimal Build"),(0,i.kt)("p",null,"For more advanced customization, you might want to create a minimal build that only includes the features you need. A good example is creating a build that can create a video from a sequence of images (e.g., from an HTML canvas), handle MP4 encoding/decoding, and support audio."),(0,i.kt)("p",null,"A community member, @Kaizodo, shared an approach that resulted in a build size of only 4.80MB. You can find the full details and a discussion in ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ffmpegwasm/ffmpeg.wasm/issues/866"},"GitHub Issue #866"),"."),(0,i.kt)("p",null,"The general strategy is to:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Start with a minimal configuration:")," Instead of removing libraries one by one, a more effective approach is to start with a minimal ffmpeg configuration. This can be achieved by using flags like ",(0,i.kt)("inlineCode",{parentName:"li"},"--disable-everything")," in the ffmpeg configuration step within the ",(0,i.kt)("inlineCode",{parentName:"li"},"Dockerfile"),"."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Enable specific components:")," After disabling everything, you can selectively enable only the encoders, decoders, muxers, demuxers, and protocols you need for your specific use case. For example: ",(0,i.kt)("inlineCode",{parentName:"li"},"--enable-encoder=libx264"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"--enable-decoder=png"),", ",(0,i.kt)("inlineCode",{parentName:"li"},"--enable-muxer=mp4"),", etc."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Include only necessary libraries:")," Make sure your ",(0,i.kt)("inlineCode",{parentName:"li"},"Dockerfile")," only builds and links the external libraries that correspond to the features you enabled (e.g., ",(0,i.kt)("inlineCode",{parentName:"li"},"libx264"),"). You can remove the build stages for any other libraries.")),(0,i.kt)("p",null,"This approach gives you control over the build content and its final size."),(0,i.kt)("p",null,"We would like to thank @Kaizodo, @harkdawg and other community members for sharing their knowledge!"),(0,i.kt)("h2",{id:"publish"},"Publish"),(0,i.kt)("p",null,"Simply run ",(0,i.kt)("inlineCode",{parentName:"p"},"npm publish")," under ",(0,i.kt)("strong",{parentName:"p"},"packages/core")," or ",(0,i.kt)("strong",{parentName:"p"},"/packages/core-mt"),"."))}d.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.