xabe.ffmpeg not working in azure app service

Viewed 644

I have a .net core application which generates video thumbnails for uploaded videos. I am using xabe.ffmpeg for this . The code runs fine in the local system and Iam able to generate the thumbnails . I have containerized this application and pushed it to azure app service . But when the code is deployed on azure app service its throws an error . I have placed the ffmpeg.exe ,ffprobe.exe , ffplay.exe inside a folder ffmpeg in wwwroot folder . the app service logs give this error

the first line is the path: /app/wwwroot/ffmpeg

2020-12-25T14:34:01.347103909Z /app/wwwroot/ffmpeg 2020-12-25T14:34:01.443016709Z [41m[30mfail[39m[22m[49m: Microsoft.AspNetCore.Server.Kestrel[13] 2020-12-25T14:34:01.443066009Z Connection id "0HM58S8AE014U", Request id "0HM58S8AE014U:00000002": An unhandled exception was thrown by the application. 2020-12-25T14:34:01.456821709Z System.ComponentModel.Win32Exception (2): No such file or directory 2020-12-25T14:34:01.462537109Z at System.Diagnostics.Process.ForkAndExecProcess(String filename, String[] argv, String[] envp, String cwd, Boolean redirectStdin, Boolean redirectStdout, Boolean redirectStderr, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) 2020-12-25T14:34:01.462555709Z at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) 2020-12-25T14:34:01.462560609Z at System.Diagnostics.Process.Start() 2020-12-25T14:34:01.463739309Z at Xabe.FFmpeg.FFmpeg.RunProcess(String args, String processPath, Nullable1 priority, Boolean standardInput, Boolean standardOutput, Boolean standardError) 2020-12-25T14:34:01.463755809Z at Xabe.FFmpeg.FFprobeWrapper.<>c__DisplayClass9_0.<RunProcess>b__0() 2020-12-25T14:34:01.463761809Z at System.Threading.Tasks.Task1.InnerInvoke() 2020-12-25T14:34:01.463766309Z at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj) 2020-12-25T14:34:01.463781109Z at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 2020-12-25T14:34:01.463786509Z --- End of stack trace from previous location where exception was thrown --- 2020-12-25T14:34:01.463790909Z at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 2020-12-25T14:34:01.463795509Z at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) 2020-12-25T14:34:01.463800009Z --- End of stack trace from previous location where exception was thrown --- 2020-12-25T14:34:01.463813709Z at Xabe.FFmpeg.FFprobeWrapper.RunProcess(String args, CancellationToken cancellationToken) 2020-12-25T14:34:01.463818109Z at Xabe.FFmpeg.FFprobeWrapper.GetStreams(String videoPath, CancellationToken cancellationToken) 2020-12-25T14:34:01.463821909Z at Xabe.FFmpeg.FFprobeWrapper.SetProperties(MediaInfo mediaInfo, CancellationToken cancellationToken) 2020-12-25T14:34:01.463825509Z at Xabe.FFmpeg.MediaInfo.Get(String filePath, CancellationToken cancellationToken) 2020-12-25T14:34:01.463829109Z at Xabe.FFmpeg.MediaInfo.Get(String filePath) 2020-12-25T14:34:01.463832609Z at Xabe.FFmpeg.FFmpeg.GetMediaInfo(String fileName) 2020-12-25T14:34:01.467009509Z at root2webAPI.Controllers.AzureStorageControllers.BlobExplorerController.GetVideoThumbnailAsync(IFormFile file, Int32 frameTarget) in /src/root2webAPI/Controllers/AzureStorageControllers/BlobExplorerController.cs:line 271 2020-12-25T14:34:01.467023809Z at root2webAPI.Controllers.AzureStorageControllers.BlobExplorerController.UploadMediaBlob(IFormFile file, String parentId) in /src/root2webAPI/Controllers/AzureStorageControllers/BlobExplorerController.cs:line 96 2020-12-25T14:34:01.467028709Z at lambda_method(Closure , Object ) 2020-12-25T14:34:01.467032109Z at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() 2020-12-25T14:34:01.467035909Z at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) 2020-12-25T14:34:01.467039409Z at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) 2020-12-25T14:34:01.467043209Z at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 2020-12-25T14:34:01.467055709Z at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) 2020-12-25T14:34:01.467060609Z at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 2020-12-25T14:34:01.467067409Z at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 2020-12-25T14:34:01.467071609Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 2020-12-25T14:34:01.467075209Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) 2020-12-25T14:34:01.467078709Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 2020-12-25T14:34:01.467089009Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 2020-12-25T14:34:01.467093409Z at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) 2020-12-25T14:34:01.467096909Z at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) 2020-12-25T14:34:01.467100509Z at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) 2020-12-25T14:34:01.467103809Z at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext]

here is my relevant .net application code

  private async Task<MediaMetadata> GetVideoThumbnailAsync(IFormFile file,int frameTarget)
    {
     var fileName = file.FileName;
     var filePath = Path.Combine(_rootPath, "videos", fileName);
     var fileExtension = Path.GetExtension(filePath);
     
     // the xabe wrapper works with only mp4 extension to create thumbnail , if the file is any other format first convert it to
     //the mp4 format and then goahead with creating the thumbnail.  
     var thumbnailImageName = fileName.Replace(fileExtension, ".jpg");
     var thumbnailImagePath = Path.Combine(_rootPath, "thumbnails", thumbnailImageName);
     
            using (Stream fileStream = new FileStream(filePath, FileMode.Create)) {
                
             await file.CopyToAsync(fileStream);
            }
    Console.WriteLine(Path.Combine(_rootPath,"ffmpeg"));
    FFmpeg.SetExecutablesPath(Path.Combine(_rootPath,"ffmpeg"));
    IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(filePath);
    var videoDuration = mediaInfo.VideoStreams.First().Duration;
    IConversion conversion = await FFmpeg.Conversions.FromSnippet.Snapshot(filePath, thumbnailImagePath , TimeSpan.FromSeconds(frameTarget));
    IConversionResult result = await conversion.Start();
    MediaMetadata media = new MediaMetadata();
    media.DurationSeconds=Convert.ToInt32(videoDuration.TotalMilliseconds);
    // media.DurationSeconds=10;
    media.ThumbnailImagePath= thumbnailImagePath;
    return media;
    
    }

could you help me out with this ..many thanks

1 Answers

I managed it to work inside Azure App Services. It was 2 years ago, and application is still working: https://xabe-convert-client.azurewebsites.net/ However, I didn't dockerize it. It works on free tier app service so try it horrible slow but works :)

The clue is to not use SetExecutablesPath because Azure changes paths somehow. I uploaded ffmpeg executables with applications.

enter image description here


It can be done using Xabe.FFmpegDownloader too :)

Related