[Extension] Create Cutlists during Playback

Discuss your Lua playlist, album art and interface scripts.
roland1
Blank Cone
Blank Cone
Posts: 44
Joined: 01 May 2014 16:49

[Extension] Create Cutlists during Playback

Postby roland1 » 10 May 2014 13:18

Hi,
I am using some open source media libraries to cut mostly .mkv files and they accept cutlists as parameters. Those cutlists are easily created with this extension while the file plays in vlc. The cutlists are stored in cutlist.txt (in vlc.config.userdatadir()) as a Lua table constructor, e.g.

Code: Select all

{ ["path/to/file"] = {123.123123, 234.234234, 345.345345, 456.456456} }
EDIT: ATM, it does not use "path/to/file" but URI.
so that an application can easily loop over a batch of files given the path to cutlist.txt.
(Those time-sequences are of course not restricted to be used as cutlists.)
Originally this extension was depending on add_callback/del_callback and it was working
better. This is a rewrite using a dialog interface. It works but it is not heavily adapted to this interface.
EDIT: The current version is adapted and offers a broad and clean interface.

Patches, Feedback and Suggestions are welcome.

Best Regards
(bad english for common amusement)

Suggestions:
-- (TODO) Buttons for play/pause, back, forward (maybe with different step-sizes)
---- DONE
-- use local file path (if available) instead of URI.
-- let vlc also cut the files? Is this possible from within an extension?
-- dialog-listview based display instead of osd?


Source:

Code: Select all

--[[ author: randomguy at videolan.org forum license: GPL --]] local DATA_FD = nil -- fill in file-dir if vlc.config.userdatadir() does not work. local DATA_FN, STEP, BIGSTEP = "cutlist.txt", 10, 120 local PATH, TIME, CHANNEL, FILE, LISTS, LIST, BTTN, DLG, INPUT -- environment. CHANNEL = { register = function(self) self.channel = vlc.osd.channel_register() return self.channel end, send = function(self, msg) vlc.osd.message(msg, self.channel or self:register()) end, unregister = function(self) if self.channel then vlc.osd.channel_clear(self.channel) end end, } local function seek(p) vlc.var.set(INPUT, "time", TIME+p) end local function save() CHANNEL:send( #LIST%2 ~= 0 and "Missing last TO-POSITION, but anyway, saving to Cutlist..." or "Saving to Cutlist..." ) for n, Ln in pairs(LISTS) do if next(Ln) == nil then LISTS[n] = nil end end FILE:write_enc(LISTS) end BTTN = { { "&q from pos", function() local maxn = #LIST if maxn%2 ~= 0 or (maxn > 0 and LIST[maxn] > TIME) then return end LIST[maxn+1] = TIME CHANNEL:send(("|<-- %d sec"):format(TIME)) end, 1, 1 }, { "&w to pos", function() local maxn = #LIST if maxn%2 == 0 or LIST[maxn] > TIME then return end LIST[maxn+1] = TIME CHANNEL:send(("-->| %d sec"):format(TIME)) end, 2, 1 }, { "&e remove pos", function() CHANNEL:send"Removing last position." LIST[#LIST] = nil end, 3, 1 }, { "&r remove item", function() CHANNEL:send"Removing file from Cutlist." LISTS[PATH] = nil end, 4, 1 }, { "&t print", function() if next(LIST) == nil then CHANNEL:send"Empty list" return end local hms, frmt = {PATH, "\n"}, "%02d:%02d:%02d" for i, sec in ipairs(LIST) do hms[#hms+1] = frmt:format(sec/3600, (sec%3600)/60, sec%60) hms[#hms+1] = i%2 ~= 0 and " - " or "\n" end CHANNEL:send(table.concat(hms)) end, 5, 1 }, { "&y save", save, 6, 1 }, { "&a <<<", function() seek(-BIGSTEP) end, 1, 2 }, { "&s <<", function() seek(-STEP) end, 2, 2 }, { "&d >", function() vlc.playlist.pause() end, 3, 2 }, { "&f >>", function() seek(STEP) end, 4, 2 }, { "&g >>>", function() seek(BIGSTEP) end, 5, 2 }, { "&z save", save, 1, 3 }, { "&x prev", function() vlc.playlist.prev() end, 2, 3 }, { "&c next", function() vlc.playlist.next() end, 3, 3 }, } ------------------------------------------------------------------------------------ local function decode(s) return loadstring("return "..s)() end local function encode(t) local buf = {} for p, tp in pairs(t) do buf[#buf+1] = (" [%q] = {%s}"):format(p, table.concat(tp, ", ")) end return "{\n"..table.concat(buf, ",\n").."\n}" end ------------------------------------------------------------------------------------ function descriptor() return { title = "Create Cutlist", version = "0.4", author = "randomguy at videolan.org forum", shortdesc = "Creates a cutlist in userdatadir.", capabilities = {"input-listener"}, } end function activate() os.setlocale("C", "numeric") for _, bttn in pairs(BTTN) do local cb = bttn[2] bttn[2] = function(...) -- preparing if not INPUT then return end TIME = vlc.var.get(INPUT, "time") if not LISTS[PATH] then LISTS[PATH] = {} end LIST = LISTS[PATH] return cb(...) end end local pd = package.config:sub(1, 1) local fp = (DATA_FD or vlc.config.userdatadir()):gsub(pd.."+$", "")..pd..DATA_FN local fr = io.open(fp, "r") if fr then LISTS = decode(fr:read"*a" or "{}") fr:close() end if type(LISTS) ~= "table" then LISTS = {} end FILE = { write = function(self, ...) local fw = io.open(fp, "w") fw:write(...) fw:close() end, write_enc = function(self, t) self:write(encode(t)) end, } DLG = vlc.dialog"Create Cutlist" for i = 1, #BTTN do DLG:add_button(unpack(BTTN[i])) end DLG:show() end function input_changed() local item = vlc.input.item() local input = vlc.object.input() PATH = item:uri() -- vlc.strings.decode_uri(item:uri()):gsub("^[^/]*//", "") INPUT = input end function deactivate() CHANNEL:unregister() vlc.deactivate() end close = deactivate
Last edited by roland1 on 10 May 2014 21:10, edited 2 times in total.

mederi
Big Cone-huna
Big Cone-huna
Posts: 1951
Joined: 15 Mar 2011 16:38
VLC version: 2.0.8
Operating System: Windows Vista/XP

Re: [Extension] Create Cutlists during Playback

Postby mederi » 10 May 2014 17:29

-- let vlc also cut the files? Is this possible from within an extension?
The extension could also use the created cutlist for some purpose in VLC. It is possible to read playlist table, then feed the playlist with new tracks having :start-time :stop-time options. The extension could skip introes, credits, commercials, ... Check the Clipper extension.
I also work on modification of Sampler extension with 3 more buttons: Read playlist, Clear playlist and Feed playlist.
-- dialog-listview based display instead of osd?
OSD space is quite limited for many entries. You rather have also a list in the dialog box.
If you add some description to start-stop time couple, you will get something like subtitle. If you implement some editing controls to add, edit, delete entries, then it is already a subtitle editor. A subtitle editor with some extra features can be a universal tool :)
Perhaps you could define fp="" at the beginning of the script for easy customization (fp="D:\\cutlist.txt"). My system does not support vlc.config.userdatadir() because of "í" character in the path. Lua needs to be somehow patched to properly support unicode strings under Windows. You could show the storage path in dialog box so user knows where it is.

roland1
Blank Cone
Blank Cone
Posts: 44
Joined: 01 May 2014 16:49

Re: [Extension] Create Cutlists during Playback

Postby roland1 » 10 May 2014 21:23

Update!

Code: Select all

local DATA_FD = nil -- fill in file-dir if vlc.config.userdatadir() does not work.
The extension could also use the created cutlist for some purpose in VLC.
Yes, but a button [let vlc cut this batch of files in the background] remains near the
top on my wish-list. So, I am interested in cutting and merging (with libvlc?).
Anyway, the next overhaul will probably be the dialog-listview (this should be possible without too much trial&error).
If you add some description to start-stop time couple, you will get something like subtitle.
You are right! Can I register a callback to trigger at start/stop or (better) on interval-change?

And it looks like not only my extension broke (due to api changes), both, Sampler and Clipper do not run on my setup.
(Maybe not a surprise, as it is 2.1)

mederi
Big Cone-huna
Big Cone-huna
Posts: 1951
Joined: 15 Mar 2011 16:38
VLC version: 2.0.8
Operating System: Windows Vista/XP

Re: [Extension] Create Cutlists during Playback

Postby mederi » 11 May 2014 15:56

The Sampler extension uses add_callback() and therefore I would like to make a modification to work only as a playlist generator.
The Clipper is extension for manual "cutting" of playlist items to prepare new playlist for playback without unwanted parts. This should work for you, too. Please check the messages to find out where the problem is. I hoped you could find some useful ideas there.
If you do some transcoding or streaming with VLC, it is done as a new track in playlist. If you save the playlist in a file, you can check used streaming options. Perhaps it is possible to generate the streaming tracks with the right options to perform the real cutting/merging of multimedia files. How to cut/merge with VLC from the command line?

roland1
Blank Cone
Blank Cone
Posts: 44
Joined: 01 May 2014 16:49

Re: [Extension] Create Cutlists during Playback

Postby roland1 » 11 May 2014 21:04

Regarding Clipper, it does not show up in menu and vlc -vvv only gives this message:

Code: Select all

[0xab05e020] lua generic warning: Error loading script ~/.local/share/vlc/lua/extensions/clipper.lua: ~/.local/share/vlc/lua/extensions/clipper.lua:903: <name> expected near 'goto'
How to cut/merge with VLC from the command line?
Taking the risk this question is rhetorical, I answer "I don't know exactly.";)
Regarding merging, I just found in the wiki:
Overall, none of the ways VLC offers to combine streams appears to merge them with correct time signatures<ref> even when replayed in VLC (causing seeking errors)...
If true (for interesting formats), that statement is a show-stopper for a rudimentary cutting (and merging) solution without external dependencies (would have been a nice addon).
Involving more playlist features wouldn't help here, but, another extension could use
the time-marks in cutlist.txt to manipulate the playlist of course.

Regards

mederi
Big Cone-huna
Big Cone-huna
Posts: 1951
Joined: 15 Mar 2011 16:38
VLC version: 2.0.8
Operating System: Windows Vista/XP

Re: [Extension] Create Cutlists during Playback

Postby mederi » 12 May 2014 09:48

Regarding Clipper:
Change goto to gotoitem for lua 5.2 compatibility.
by javimixet on: May 9 2014

line 903
changed vlc.playlist.goto(play_id)
to vlc.playlist.gotoitem(play_id)

https://mailman.videolan.org/pipermail/ ... 84271.html


Return to “Scripting VLC in lua”

Who is online

Users browsing this forum: No registered users and 10 guests