mifi/editly

audioTracks trigger "Error: EBUSY: resource busy or locked"

morjanmihail opened this issue · 9 comments

Hello!

Whenever I use audioTracks or audioFilePath the build triggers this error in console.

Caught error [Error: EBUSY: resource busy or locked, unlink 'xxx\xxxx\editly-tmp-Ke_F7ZWJbBsyW52E7Tz
5t\audio-mixed.flac'] {
  errno: -4082,
  code: 'EBUSY',
  syscall: 'unlink',
  path: 'xxxx\xxxx\\editly-tmp-Ke_F
7ZWJbBsyW52E7Tz5t\\audio-mixed.flac'

So far I tried to restart my pc, to reinstall editly globally, to close every node service and restart and same result. My json file looks like this:


{
  "width": 1080,
  "height": 1920,
  "allowRemoteRequests": true,
  "outPath": "./161565973600534528.mp4",
  audioTracks: [
    {
      path: './src/assets/audio/audio03.mp3',
      cutFrom: 0
    }
  ],
  "clips": [
    {
      "duration": 10,
      "layers": [
        {
          "type": "image",
          "path": "xxx/xxx/EzphBFPVEAMKC8D.jpg"
        },
        {
          "type": "image-overlay",
          "path": "./src/assets/logo.png",
          "width": 0.2,
          "position": {
            "x": 0.95,
            "y": 0.03,
            "originX": "right"
          }
        },
        {
          "type": "news-title",
          "text": "Testing Title"
        },
        {
          "type": "subtitle",
          "text": "Testing description",
          "backgroundColor": "rgba(0,0,0,0.5)"
        }
      ]
    }
  ]
}

The command I used to execute is:

editly 161565973600534528.json5

FFMPEG Logs:

100% Done with transition, switching to next transitionFromClip (1)trate=6197.5kbits/s speed=0.798x    
No more transitionFromClip, done
Caught error [Error: EBUSY: resource busy or locked, unlink 'xxx\editly-tmp-5J8yBsXlrmd3eHpj8IaBf
\audio-mixed.flac'] {
  errno: -4082,
  code: 'EBUSY',
  syscall: 'unlink',
  path: 'xxx\\editly-tmp-5J8yBsXlrmd3eHpj8IaBf\\audio-mixed.flac'
}
[mp4 @ 000001d11fd7f4c0] Starting second pass: moving the moov atom to the beginning of the file
frame=  250 fps= 19 q=-1.0 Lsize=    9313kB time=00:00:09.98 bitrate=7641.6kbits/s speed=0.774x
video:9146kB audio:158kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.094986%
[libx264 @ 000001d11fd16680] frame I:1     Avg QP:17.13  size:376795
[libx264 @ 000001d11fd16680] frame P:63    Avg QP:17.40  size:122221
[libx264 @ 000001d11fd16680] frame B:186   Avg QP:21.80  size:  6926
[libx264 @ 000001d11fd16680] consecutive B-frames:  0.8%  0.0%  0.0% 99.2%
[libx264 @ 000001d11fd16680] mb I  I16..4: 12.4% 36.4% 51.2%
[libx264 @ 000001d11fd16680] mb P  I16..4:  1.8%  1.4%  1.1%  P16..4: 34.1% 25.3% 19.5%  0.0%  0.0%    skip:16.8%
[libx264 @ 000001d11fd16680] mb B  I16..4:  0.3%  0.1%  0.0%  B16..8: 21.1%  2.0%  0.6%  direct: 2.9%  skip:73.0%  L0:39.0% L1:4
4.9% BI:16.1%
[libx264 @ 000001d11fd16680] 8x8 transform intra:31.5% inter:47.6%
[libx264 @ 000001d11fd16680] coded y,uvDC,uvAC intra: 39.6% 58.6% 38.8% inter: 15.4% 12.1% 4.7%
[libx264 @ 000001d11fd16680] i16 v,h,dc,p: 46% 31%  2% 20%
[libx264 @ 000001d11fd16680] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 18% 17% 29%  5%  9%  6%  6%  5%  4%
[libx264 @ 000001d11fd16680] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 35% 18% 12%  5%  7%  7%  5%  6%  4%
[libx264 @ 000001d11fd16680] i8c dc,h,v,p: 41% 25% 28%  5%
[libx264 @ 000001d11fd16680] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 000001d11fd16680] ref P L0: 48.4% 16.6% 18.7% 16.3%
[libx264 @ 000001d11fd16680] ref B L0: 67.1% 13.2% 19.7%
[libx264 @ 000001d11fd16680] ref B L1: 94.7%  5.3%
[libx264 @ 000001d11fd16680] kb/s:7492.00
[aac @ 000001d11fd17f00] Qavg: 1162.946

So somehow it finish his job but it has that error which trigger further errors. And one more thing, how can I get rid of all the automatic created temp folders? Without a cronjob to delete them automatically it will flood the server.

Many thanks in advance!

  • [ yes ] I have tried with the newest version of editly: npm i -g editly or npm i editly@latest
  • [ yes ] I have tried ffmpeg newest stable version
  • [ yes ] I have searched for existing issues
mifi commented

Hi! I'm assuming you're on Windows. I'm not 100% sure how file locking works on Windows, but it could be some race condition where a new ffmpeg is started before the previous one has closed.

This problem persist on both, Windows 10 and Ubuntu 20.

mifi commented

can you show me the full error output on ubuntu? I have never seen this error happen on Ubuntu and it shouldn't because ubuntu doesn't lock files. Even on google I cannot find this error in ubuntu:
https://www.google.com/search?q=EBUSY%3A+resource+busy+or+locked+%22ubuntu%22

My current environment from ubuntu is messed up. The moment I'll fix it will come back. Regarding your search results, I tried everything from it but nothing is working for me (from reinstalling, closing every process, restarting pc, etc.). It's most probably like you said, the race conditions between ffmpegs. The fun thing is that it is compiling and working, but with this error in console.

This appears to be caused by calling fsExtra.remove(tmpDir) before outProcess has completed in this code block:

editly/index.js

Lines 385 to 390 in 65551e7

if (!keepTmp) await fsExtra.remove(tmpDir);
}
try {
if (verbose) console.log('Waiting for output ffmpeg process to finish');
await outProcess;

When merging several mp4 videos with the original clip audio, this error killed the process before the output mp4 was finalized, resulting in an invalid output file.

mifi commented

nice find! would you like to submit a PR?

Hello !
as @woolite64 mentioned this problem is happening because of file being busy and when file is busy it's locked and fxExtra can't remove it so it throws error
easiest solution to this problem is to add keepTmp : true to edit spec

i also came up with this solution and it might not be optimal and there might be better ways to do this

editly/index.js

Lines 385 to 390 in 65551e7

if (!keepTmp) await fsExtra.remove(tmpDir);
}
try {
if (verbose) console.log('Waiting for output ffmpeg process to finish');
await outProcess;

replacing the keepTmp condition to this condition below

 if (!keepTmp){
      let isBussy = true;
      while(isBussy){
      // await  delay(100);
        try {
          await fsExtra.remove(tmpDir)
          isBussy = false;
        } catch (errorr) {
          if(errorr.code != "EBUSY") isBussy=false;
        };
      };
    };

we can also use some sort of delay function for the while loop

Sorry for the slow response. For this bit of code:

editly/index.js

Lines 377 to 393 in 65551e7

outProcess.stdin.end();
} catch (err) {
outProcess.kill();
throw err;
} finally {
if (verbose) console.log('Cleanup');
if (frameSource1) await frameSource1.close();
if (frameSource2) await frameSource2.close();
if (!keepTmp) await fsExtra.remove(tmpDir);
}
try {
if (verbose) console.log('Waiting for output ffmpeg process to finish');
await outProcess;
} catch (err) {
if (outProcessExitCode !== 0 && !err.killed) throw err;
}

This was the approach I was going to take:

    outProcess.stdin.end();
  } catch (err) {
    outProcess.kill();
    if (!keepTmp) await fsExtra.remove(tmpDir);
    throw err;
  } finally {
    if (verbose) console.log('Cleanup');
    if (frameSource1) await frameSource1.close();
    if (frameSource2) await frameSource2.close();
  }

  try {
    if (verbose) console.log('Waiting for output ffmpeg process to finish');
    await outProcess;
  } catch (err) {
    if (outProcessExitCode !== 0 && !err.killed) throw err;
  } finally {
    if (!keepTmp) await fsExtra.remove(tmpDir);
  }

@mifi This would clear the temp folder if an error occurred, as well as after the process has completed. Does this look reasonable? I haven't tested this yet, my Windows environment is a bit wonky.

mifi commented

if someone wantts to provide a fix, PR is welcome:)