The Lemon
The Lemon

Reputation: 1389

FFmpeg on Azure Function call running slowly and producing an empty output file

I'm trying to make a function which uses ffmpeg, so far I haven't been able to get anything other than the -version command to work properly. When I try to run a simple ffmpeg -i {input file path} {output file path} command, the function seems to get stuck for 3-4 minutes (in the process creating an empty output file), then try again and produce the error 'file already exists'. I've tried switching between the 64 bit ffmpeg.exe and the 32 bit ffmpeg.exe with the function running as both a 32 and 64 bit function. My code and the associated logs from trying to run the code are included below, if anyone can tell me what I'm doing wrong or how to get the process to work it would be greatly appreciated. Thanks in advance, Cuan

edit: The process works on kudu with the same files, the output is shown at the bottom. On kudu the process ran in under half a minute, clearly something is causing the function process to hang, if anyone has advice it would be greatly appreciated. Thanks again, Cuan.

second edit: I tried adding the -y to the end of my command, this works in that it no longer complains about overwriting, but alas it now just hangs twice due to timeout. (output at the bottom)

edit the third: azure has a way to let you run functions locally, my function ran into the same issues on the local version but: as it turns out the actual processing is done within a few seconds, it just takes forever to decide to write to a file - if you terminate the process manually after the process had been running for ~ 10 seconds the file immediately gets written. Again, any help is appreciated. Cuan.

Run.csx:

using System.Net;
using System;
using System.Diagnostics;
using System.ComponentModel;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");
    Process process = new Process();
    process.StartInfo.FileName = @"D:\home\site\wwwroot\HttpTestFunction\ffmpeg64.exe";
    string tmp = String.Format("-i \"" + "Airdocs Background Video.mp4" + "\" \"" + "tmpOut2.mp4" + "\"");
    log.Info("ffmpeg argument is: "+tmp);
    process.StartInfo.Arguments = tmp;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.WorkingDirectory = @"D:\home\site\wwwroot\HttpTestFunction";
    process.Start();
    log.Info("process started");
    string output = process.StandardOutput.ReadToEnd();
    string err = process.StandardError.ReadToEnd();
    log.Info("output:" + output);
    log.Info("error:"+err);
    process.WaitForExit();
}

Logs:

2017-10-14T02:17:10.514 Function started (Id=e4ec7d1e-2bcb-4b74-8af2-15124f1576fb)
2017-10-14T02:17:10.639 C# HTTP trigger function processed a request.
2017-10-14T02:17:10.639 ffmpeg argument is: -i "Airdocs Background Video.mp4" "tmpOut2.mp4"
2017-10-14T02:17:10.779 process started
2017-10-14T02:18:15  No new trace in the past 1 min(s).
2017-10-14T02:19:15  No new trace in the past 2 min(s).
2017-10-14T02:20:15  No new trace in the past 3 min(s).
2017-10-14T02:21:02.188 Function started (Id=b2ae9b59-8933-42e3-986c-fd26a6886285)
2017-10-14T02:21:02.188 C# HTTP trigger function processed a request.
2017-10-14T02:21:02.188 ffmpeg argument is: -i "Airdocs Background Video.mp4" "tmpOut2.mp4"
2017-10-14T02:21:02.252 process started
2017-10-14T02:21:02.377 output:
2017-10-14T02:21:02.377 error:ffmpeg version N-87353-g183fd30 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib
  libavutil      55. 76.100 / 55. 76.100
  libavcodec     57.106.101 / 57.106.101
  libavformat    57. 82.101 / 57. 82.101
  libavdevice    57.  8.101 / 57.  8.101
  libavfilter     6.105.100 /  6.105.100
  libswscale      4.  7.103 /  4.  7.103
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Airdocs Background Video.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp41isom
    creation_time   : 2017-09-08T11:55:11.000000Z
  Duration: 00:00:24.02, start: 0.000000, bitrate: 105 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 104 kb/s, 30.30 fps, 30.30 tbr, 30k tbn, 60 tbc (default)
    Metadata:
      creation_time   : 2017-09-08T11:55:11.000000Z
      handler_name    : VideoHandler
      encoder         : AVC Coding
File 'tmpOut2.mp4' already exists. Overwrite ? [y/N] Not overwriting - exiting
2017-10-14T02:21:02.392 Function completed (Success, Id=b2ae9b59-8933-42e3-986c-fd26a6886285, Duration=205ms)
2017-10-14T02:22:10.563 Function completed (Failure, Id=e4ec7d1e-2bcb-4b74-8af2-15124f1576fb, Duration=300047ms)
2017-10-14T02:22:10.610 Microsoft.Azure.WebJobs.Host: Timeout value of 00:05:00 was exceeded by function: Functions.HttpTestFunction.

Kudu code (just running the ffmpeg command directly, not the run.csx file):

D:\home\site\wwwroot\HttpTestFunction>ffmpeg -i "Airdocs Background Video.mp4" tmpout3.mp4


ffmpeg version N-87196-g6cadbb1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.1.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-zlib
  libavutil      55. 74.100 / 55. 74.100
  libavcodec     57.105.100 / 57.105.100
  libavformat    57. 81.100 / 57. 81.100
  libavdevice    57.  8.100 / 57.  8.100
  libavfilter     6.101.100 /  6.101.100
  libswscale      4.  7.103 /  4.  7.103
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Airdocs Background Video.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp41isom
    creation_time   : 2017-09-08T11:55:11.000000Z
  Duration: 00:00:24.02, start: 0.000000, bitrate: 105 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 104 kb/s, 30.30 fps, 30.30 tbr, 30k tbn, 60 tbc (default)
    Metadata:
      creation_time   : 2017-09-08T11:55:11.000000Z
      handler_name    : VideoHandler
      encoder         : AVC Coding
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 00000000005fc5a0] using SAR=1/1
[libx264 @ 00000000005fc5a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 00000000005fc5a0] profile High, level 3.2
[libx264 @ 00000000005fc5a0] 264 - core 152 r2851 ba24899 - H.264/MPEG-4 AVC codec - Copyleft 2003-2017 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'tmpout3.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp41isom
    encoder         : Lavf57.81.100
    Stream #0:0(und): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=-1--1, 30.30 fps, 16k tbn, 30.30 tbc (default)
    Metadata:
      creation_time   : 2017-09-08T11:55:11.000000Z
      handler_name    : VideoHandler
      encoder         : Lavc57.105.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=  728 fps= 39 q=29.0 Lsize=      62kB time=00:00:23.92 bitrate=  21.1kbits/s speed=1.28x    
video:52kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 17.915474%
[libx264 @ 00000000005fc5a0] frame I:4     Avg QP:12.46  size:  6102
[libx264 @ 00000000005fc5a0] frame P:184   Avg QP:16.94  size:    45
[libx264 @ 00000000005fc5a0] frame B:540   Avg QP:20.50  size:    37
[libx264 @ 00000000005fc5a0] consecutive B-frames:  1.1%  0.0%  0.0% 98.9%
[libx264 @ 00000000005fc5a0] mb I  I16..4: 66.3% 30.4%  3.3%
[libx264 @ 00000000005fc5a0] mb P  I16..4:  0.0%  0.0%  0.0%  P16..4:  0.0%  0.0%  0.0%  0.0%  0.0%    skip:100.0%
[libx264 @ 00000000005fc5a0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.0%  0.0%  0.0%  direct: 0.0%  skip:100.0%  L0:12.3% L1:87.7% BI: 0.0%
[libx264 @ 00000000005fc5a0] 8x8 transform intra:30.5% inter:14.3%
[libx264 @ 00000000005fc5a0] coded y,uvDC,uvAC intra: 2.3% 2.2% 2.1% inter: 0.0% 0.0% 0.0%
[libx264 @ 00000000005fc5a0] i16 v,h,dc,p: 93%  6%  2%  0%
[libx264 @ 00000000005fc5a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 28% 41% 31%  0%  0%  0%  0%  0%  0%
[libx264 @ 00000000005fc5a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 39% 17% 16%  5%  4%  5%  6%  3%  5%
[libx264 @ 00000000005fc5a0] i8c dc,h,v,p: 93%  6%  1%  0%
[libx264 @ 00000000005fc5a0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 00000000005fc5a0] ref B L1: 98.2%  1.8%
[libx264 @ 00000000005fc5a0] kb/s:17.57



D:\home\site\wwwroot\HttpTestFunction> 

Output on azure with the -y command

2017-10-25T04:34:45.519 Compilation succeeded.
2017-10-25T04:34:46.160 Function started (Id=18880991-c93a-42a3-96b6-7df283e3bdb4)
2017-10-25T04:34:46.300 C# HTTP trigger function processed a request.
2017-10-25T04:34:46.300 ffmpeg argument is: -i "Airdocs Background Video.mp4" "tmpOut2.mp4" -y
2017-10-25T04:34:46.394 process started
2017-10-25T04:36:46  No new trace in the past 1 min(s).
2017-10-25T04:37:46  No new trace in the past 2 min(s).
2017-10-25T04:38:37.947 Function started (Id=c7f7f768-c53b-4074-a0c2-8391848bbd80)
2017-10-25T04:38:37.963 C# HTTP trigger function processed a request.
2017-10-25T04:38:37.963 ffmpeg argument is: -i "Airdocs Background Video.mp4" "tmpOut2.mp4" -y
2017-10-25T04:38:38.025 process started
2017-10-25T04:39:46  No new trace in the past 1 min(s).
2017-10-25T04:39:46.258 Function completed (Failure, Id=18880991-c93a-42a3-96b6-7df283e3bdb4, Duration=300079ms)
2017-10-25T04:39:46.321 Microsoft.Azure.WebJobs.Host: Timeout value of 00:05:00 was exceeded by function: Functions.HttpTestFunction.

Upvotes: 2

Views: 3027

Answers (2)

The Lemon
The Lemon

Reputation: 1389

as it turns out, the entire problem was caused by

string output = process.StandardOutput.ReadToEnd();
string err = process.StandardError.ReadToEnd();

ffmpeg runs with a lot of output/error messages, this was overloading the buffer and causing the whole thing to just hang. The solution was to make this process happen event by event

process.OutputDataReceived += new DataReceivedEventHandler(
    (s, e) => 
    { 
        log.Info("O: "+e.Data);
    }
);
process.ErrorDataReceived += new DataReceivedEventHandler(
    (s, e) => 
    { 
        log.Info("E: "+e.Data);
    }
);
//start process
process.Start();
log.Info("process started");
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();

using this instead of the 'ReadToEnd()' solved all my problems, it now works properly and the output and error lines are still being captured.

Upvotes: 6

Bruce Chen
Bruce Chen

Reputation: 18465

File 'tmpOut2.mp4' already exists. Overwrite ? [y/N] Not overwriting - exiting

You could add the -y option with your command for overwriting output files without asking as follows:

ffmpeg -i {input file path} {output file path} -y

For more options, you could refer to here.

Moreover, you could leverage kudu to test the conversion as follows:

enter image description here

2017-10-14T02:22:10.610 Microsoft.Azure.WebJobs.Host: Timeout value of 00:05:00 was exceeded by function: Functions.HttpTestFunction.

It seems you are using the Dynamic SKUs. As host.json mentioned about functionTimeout as follows:

Value indicating the timeout duration for all functions.

  • In Dynamic SKUs, the valid range is from 1 second to 10 minutes and the default value is 5 minutes.
  • In Paid SKUs there is no limit and the default value is null (indicating no timeout).

Note: If the conversation would cost a lot of time, you need to increase the functionTimeout or change the SKUs type. Moreover, for Paid SKUs, you need to enable Always On feature, more details you could refer to here.

Upvotes: 2

Related Questions