Search code examples
windowsfile-ioluavlcdelete-file

VLC Media Player LUA Extension fails detecting whether the media file actually exists or not in Windows


As I stated in Q-title, I am trying to utilize an existing VLC extension developed in LUA programming language.

The Lua extension can be referred from here, when I correctly place this extension in %ProgramFiles%\VideoLAN\VLC\lua\extensions path and then open any video/audio file and run it and then when I select View > Remove current file from playlist and disk option, it closes the currently playing media file & throws this error: lua info: [vlc-delete] error: File does not exist.

Not sure but I suspect this is due to Windows quotes issue when FileName and/or FilePath contains spaces in them. And also from the error, it seems that io.popen("if exist " .. file .. " (echo 1)") : read "*l" == "1" isn't reliable for correctly detecting whether file actually exists or not.

I am relatively new to Lua programming, so can anyone assist about any better methods for checking whether file exists or not that works in latest VLC versions like 3.x+(cause I am using VLC 3.0.17.4 64Bit in Windows 10/11 64Bit), or just assist fix this mentioned issue ?

Note that when the script calls fileExists method, it does takes care of quotes properly: if not fileExists("\"" .. file .. "\"") then return nil, "File does not exist" end


Solution

  • After hours of troubleshooting, I was able to fix the issue, which was due to the way the quoted(space-containing) file path was passed to another function and the Lua library method of os.remove not working on the passed parameter.

    So I just had an idea, I am mainly using Windows OS only, then why not convert the script to rely on Windows OS core(batch/cmd) functions only and do the safe checking of whether file exists and then delete with those core Windows functions too.

    And so I just did that and got the plugin to actually check whether the file exists and delete the file, if it does then delete it. Here's the working code:

    -- Copy this file to %ProgramFiles%\VideoLAN\VLC\lua\extensions\ and restart VLC Media player.
    function descriptor()
        return {
            title = "VLC Delete Media File(Windows only)";
            version = "1.0";
            author = "Vicky Dev";
            shortdesc = "&Remove current file from playlist and disk";
            description = [[
    <h1>VLC Delete Media File(Windows only)</h1>"
    When you're playing a file, use this to easily
    delete the current file from your <b>playlist</b> and <b>disk</b> with one click.<br>
    Disclaimer: The author is not responsible for damage caused by this extension.
            ]];
        }
    end
    
    function sleep(seconds)
        local t0 = os.clock()
        local tOriginal = t0
        while os.clock() - t0 <= seconds and os.clock() >= tOriginal do end
    end
    
    function removeItem()
        local id = vlc.playlist.current()
        vlc.playlist.delete(id)
        vlc.playlist.gotoitem(id + 1)
        vlc.deactivate()
    end
    
    function activate()
        local item = vlc.input.item()
        local uri = item:uri()
        uri = string.gsub(uri, "^file:///", "")
        uri = vlc.strings.decode_uri(uri)
        path = string.gsub(uri, "/", "\\")
        vlc.msg.info("[VLC Delete Media File(Windows only)] removing: "..uri.." : "..path)
        removeItem()
        retval, err = os.execute("if exist ".."\""..path.."\"".." @(call )")
        if (type(retval) == 'number' and retval == 0) then
            os.execute("del /f /a /q ".."\""..path.."\"")
        end
    end
    
    function click_ok()
        d:delete()
        vlc.deactivate()
    end
    
    function deactivate()
        vlc.deactivate()
    end
    
    function close()
        deactivate()
    end
    
    function meta_changed()
    end
    

    Hope this helps anyone who wants this cool feature of deleting the media files from player itself, instead of going to the location and doing it.