{"id":13430910,"url":"https://github.com/sps014/FFmpegBlazor","last_synced_at":"2025-03-16T06:31:41.075Z","repository":{"id":37962663,"uuid":"314019159","full_name":"sps014/FFmpegBlazor","owner":"sps014","description":"FFmpeg on Web Assembly","archived":false,"fork":false,"pushed_at":"2024-10-21T17:22:31.000Z","size":10479,"stargazers_count":133,"open_issues_count":1,"forks_count":19,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-22T07:18:12.687Z","etag":null,"topics":["csharp","dotnet","webassembly"],"latest_commit_sha":null,"homepage":"https://ffmpegblazor.netlify.app/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sps014.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-18T18:14:38.000Z","updated_at":"2024-10-21T17:22:35.000Z","dependencies_parsed_at":"2024-04-09T22:50:50.514Z","dependency_job_id":"2d3a96b3-56f9-4365-afc7-6d7b868dadea","html_url":"https://github.com/sps014/FFmpegBlazor","commit_stats":{"total_commits":79,"total_committers":2,"mean_commits":39.5,"dds":"0.025316455696202556","last_synced_commit":"fa362ce3cab94fe2904d8df95706fe90751522a3"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sps014%2FFFmpegBlazor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sps014%2FFFmpegBlazor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sps014%2FFFmpegBlazor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sps014%2FFFmpegBlazor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sps014","download_url":"https://codeload.github.com/sps014/FFmpegBlazor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221656479,"owners_count":16858779,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","webassembly"],"created_at":"2024-07-31T02:00:58.903Z","updated_at":"2025-03-16T06:31:41.062Z","avatar_url":"https://github.com/sps014.png","language":"C#","funding_links":[],"categories":["Sample Projects"],"sub_categories":["Others"],"readme":"# FFmpegBlazor (Blazor WASM)\n\n[![NuGet Badge](https://buildstats.info/nuget/FFmpegBlazor)](https://www.nuget.org/packages/FFmpegBlazor/)\n![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)\n\n \nFFmpegBlazor provides ability to utilize ffmpeg.wasm from Blazor Wasm C#.\\\n[ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) is a pure Webassembly / Javascript  port of FFmpeg. It enables video \u0026 audio record, convert and stream right inside browsers.\\\nSupports Lazy loading of ffmpeg binary. It is self hosted version one time download of core ffmpeg wasm lib will be 25Mb.\n\n##### Video Tutorial : [Link](https://www.youtube.com/watch?v=5L4utDgFAAg) Credit Dev Express\n\n### Installation\n\nDownload package via  [Nuget](https://www.nuget.org/packages/FFmpegBlazor/)  or DotNet CLI and you are good to go , no extra configuration required.\n```cli\ndotnet add package FFmpegBlazor \n```\n[API Documentation](https://github.com/sps014/FFmpegBlazor/wiki)\n\n### Running WASM App \n\n\n#### Running Locally\n\n**Currently we need to use a workaround to run FFmpegApps on web assembly, this will be removed in .NET 10 (Early September 2025) once Multi threading support is available on WASM, and these headers are injected.**\n\nWe need to add 2 headers in Blazor WASM-local-server and in actual deployment static server also\n\n```\nCross-Origin-Embedder-Policy: require-corp\nCross-Origin-Opener-Policy: same-origin\n```\nTo do so we can create a `web.config` file in root of our project with content \n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cconfiguration\u003e\n\t\u003csystem.webServer\u003e\n\t\t\u003chttpProtocol\u003e\n\t\t\t\u003ccustomHeaders\u003e\n\t\t\t\t\u003cadd name=\"Cross-Origin-Embedder-Policy\" value=\"require-corp\"/\u003e\n\t\t\t\t\u003cadd name=\"Cross-Origin-Opener-Policy\" value=\"same-origin\"/\u003e\n\t\t\t\u003c/customHeaders\u003e\n\t\t\u003c/httpProtocol\u003e\n\t\u003c/system.webServer\u003e\n\n\u003c/configuration\u003e\n```\nUse [IIS Express](https://github.com/sps014/FFmpegBlazor/issues/9#issuecomment-1059950578) to run apps locally.\nAlso In actual deployment we need to add these 2 headers in server config to avoid `SharedArrayBuffer not defined` error.\nYou can check Netlify deployment [sample here](https://github.com/sps014/ffmpegBlazor-Deployed).\n\u003cbr/\u003eThanks to [@aokocax](https://github.com/aokocax) for helping with it.\n\n\n#### Running Published\n\nRun following in published wwwroot folder with dotnet serve tool. \n\n`dotnet serve -p 8000 -h \"Cross-Origin-Embedder-Policy: require-corp\" -h \"Cross-Origin-Opener-Policy: same-origin\"`\n\n### Sample \nHere is a sample page to convert mp4 to mp3 and play it in browser.\n\n```razor\n\n@page \"/\"\n@using FFmpegBlazor\n@inject IJSRuntime Runtime\n@using Microsoft.AspNetCore.Components.Forms\n\n\n\u003cInputFile OnChange=\"fileLoad\" /\u003e\u003cbr /\u003e \u003cbr /\u003e\n\u003cvideo width=\"300\" height=\"200\" autoplay controls src=\"@url\" /\u003e\u003cbr /\u003e\u003cbr /\u003e\n\u003cbutton class=\"btn btn-primary\" @onclick=\"Process\"\u003eConvert Mp3\u003c/button\u003e\u003cbr /\u003e\u003cbr /\u003e\n\u003caudio controls src=\"@url2\" /\u003e\n\n@code\n{\n    string url; string url2;\n    FFMPEG ff;\n    byte[] buffer;\n\n    protected override async Task OnInitializedAsync()\n    {\n        if (FFmpegFactory.Runtime == null)\n        {\n            FFmpegFactory.Logger += WriteLogs;\n            FFmpegFactory.Progress += ProgressChange;\n        }\n\n        //initialize Library\n        await FFmpegFactory.Init(Runtime);\n    }\n\n    async void fileLoad(InputFileChangeEventArgs v)\n    {\n        //get fist file from input selection\n        var file = v.GetMultipleFiles()[0];\n\n        //read all bytes\n        using var stream = file.OpenReadStream(100000000); //Max size for file that can be read\n        buffer = new byte[file.Size];\n\n        //read all bytes\n        await stream.ReadAsync(buffer);\n\n        //create a video link from buffer so that video can be played\n        url = FFmpegFactory.CreateURLFromBuffer(buffer, \"myFile.mp4\", file.ContentType);\n\n        //reRender DOM\n        StateHasChanged();\n    }\n\n    async void Process()\n    {\n        //create an instance\n        ff = FFmpegFactory.CreateFFmpeg(new FFmpegConfig() { Log = true });\n\n        //download all dependencies from cdn\n        await ff.Load(); \n\n        if (!ff.IsLoaded) return;\n\n        //write buffer to in-memory files (special emscripten files, Ffmpeg only interact with this file)\n        ff.WriteFile(\"myFile.mp4\", buffer);\n\n        //Pass CLI argument here equivalent to ffmpeg -i myFile.mp4 output.mp3\n        await ff.Run(\"-i\", \"myFile.mp4\", \"output.mp3\");\n\n        //delete in-memory file\n        //ff.UnlinkFile(\"myFile.mp4\");\n    }\n\n    async void ProgressChange(Progress m)\n    {\n         // display progress % (0-1)\n        Console.WriteLine($\"Progress {m.Ratio}\");\n\n        //if ffmpeg processing is complete (generate a media URL so that it can be played or alternatively download that file)\n        if (m.Ratio == 1)\n        {\n            //get bytepointer from c wasm to c#\n            var res = await ff.ReadFile(\"output.mp3\");\n\n\n            //generate a url from file bufferPointer\n            url2 = FFmpegFactory.CreateURLFromBuffer(res, \"output.mp3\", \"audio/mp3\");\n\n            //Download the file instantly\n\n            //FFmpegFactory.DownloadBufferAsFile(res, \"output.mp3\", \"audio/mp3\");\n\n            StateHasChanged();\n        }\n    }\n\n    void WriteLogs(Logs m)\n    {\n        Console.WriteLine(m.Type + \" \" + m.Message);\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsps014%2FFFmpegBlazor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsps014%2FFFmpegBlazor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsps014%2FFFmpegBlazor/lists"}