GNU Emacs video editor mode for editing video using an Edit Decision List [EDL].
GNEVE is an extension for GNU Emacs to provide flexible EDL (Edit Decision List) video editing facilities as part of a free, multimedia production toolchain. GNEVE is under active development, currently with three developers working towards a first beta release. GNEVE depends on the freely available MPlayer software for previewing, and the latest, free MLT framework/video editor for EDL processing. The software is keystroke driven, with flexible preview and render functionalities. GNEVE is written in Emacs Lisp, and runs on GNU/Linux.
Dependencies: MLT framework: http://www.mltframework.org/twiki/bin/view/MLT/
[formerly: avidemux 2.4, mplayer 1.0 [patched]]
Developers:
Martin Howse
Arn Matyasi
Gabor Torok
Links:
Download latest release: http://1010.co.uk/gneve.el
Savannah: https://savannah.nongnu.org/projects/gneve/
Development notes [MH] follow:
[see also: gneve_development ]
1] export from Kino as MPEG4 AVI single pass [btw. have to edit appropriate script in: /usr/share/kino/scripts/exports/ so that mp3 is libmp3lame to avoid halting at: "unknown encoder mp3"]
2] potentially use --force-smart on avidemux2_cli (in gneve.el)
With thanks to: Arnold Matyasi and Gabor Torok
render-buffer-as-subtitles:
1 0:01:04,050 --> 0:01:07,000 Hello Guenther. See you in a moment! 2 0:01:12,000 --> 0:01:14,080 May I present: State secretary von Weinlaub.
and so on as numbered
(also for regions to test, render and play region)
leak.el updated over last paste!
Using patched MPlayer and avidemux for rendering
M-x gneve-mode
Keys in buffer:
K next-frame L pause Q one-sec-back W one-sec-forward E mark-start R mark-end H write-marks V open-film Y goto-start X goto-end C goto-point P render S buffer-save Z buffer-preview U region-preview
ADMW0002 01 videos Name : /~/gneve/test1.avi ## source file 05 segments ## number of segments Start : 0 ## start frame number Size : 100 ## length in frames Ref : 0 Start : 3000 Size : 100 Ref : 0 Start : 5000 Size : 100 Ref : 0 Start : 6000 Size : 100 Ref : 0 Start : 8000 Size : 100 Ref : 0 Audio codec : lame Audio filter : audioNormalizeMode=0 audioResampleMode=0 audioDRC=0 audioShift=0 audioDelay=0 audioFreq=48000 audioChannelConv=0 Audio conf : audioProcessMode=0 audioMP3mode=0 audioMP3bitrate=128 audioMP3preset=0 Video start-end : 0 499 ## length total in frames container :0
thus we need to:
1] convert start-time/end-times to frames
2] subtract for length
3] make total length
4] format correctly and wrap
5] call avidemux with this (temp) saved EDL file:
avidemux2 --load test2.edl --video-process --save test.avi --quit
(and for previewing now play this)
to provide floating point accuracy in GNEVE:
mplayer.c line 5170:
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_TIME_POSITION=%.6f\n", pos);
http://blogs.bl0rg.net/netzstaub/2005/09/06/algorithmic-movie-editing-in-lisp/
1] Convert file or region to (semi-)temporary SMIL file for rendering in Kino (for example) - can we do this on commandline?
what other potential rendering engines?
smilutil and mplex: http://www.mail-archive.com/mjpeg-users@lists.sourceforge.net/msg07052.html
2] Sample SMIL EDL:
<?xml version="1.0"?> <smil xmlns="http://www.w3.org/2001/SMIL20/Language"> <body> <seq> <video src="capture016.dv" clipBegin="00:00:00.000" clipEnd="00:04:39.960"/> </seq>
Some progress in navigating video file and marking in and out points in buffer:
1) Navigate with C-q and C-w (back and forwards), C-k frame by frame (should change bindings), C-l toggles pause.
2) Mark start point with C-e. End points with C-r
3) Insert these into GNEVE buffer with H
;;; make a mode - keys and so on (defvar gneve-mode-map nil "local keymap for gneve") ;;(setq gneve-mode-map nil) (if gneve-mode-map nil (setq gneve-mode-map (make-sparse-keymap)) (define-key gneve-mode-map "\C-k" 'next-frame) (define-key gneve-mode-map "\C-l" 'pause) (define-key gneve-mode-map "\C-q" 'one-sec-back) (define-key gneve-mode-map "\C-w" 'one-sec-forward) (define-key gneve-mode-map "\C-e" 'mark-start) (define-key gneve-mode-map "\C-r" 'mark-end) (define-key gneve-mode-map "H" 'write-marks)) (defun gneve-mode() "EDL and mplayer based GNU Emacs video editing mode" (interactive) (start-process "my-process" "boo" "/root/MPlayer-1.0rc1/mplayer" "-edlout" "/root/test.edl" "-slave" "-quiet" "/root/possession.avi") (pop-to-buffer "*GNEVE*" nil) (kill-all-local-variables) (setq major-mode 'gneve-mode) (setq mode-name "gneve") (use-local-map gneve-mode-map)) (defun next-frame () (interactive) (process-send-string "my-process" "frame_step\n")) (defun pause () (interactive) (process-send-string "my-process" "pause\n")) (defun write-marks () ;; copy/write both last-in and last-out to end of gneve buffer (interactive) (switch-to-buffer "*GNEVE*") (goto-char (point-max)) (insert (format "%s %s" lastin lastout))) (defun one-sec-back () (interactive) (process-send-string "my-process" "seek -0.5\n")) (defun one-sec-forward () (interactive) (process-send-string "my-process" "seek 0.1\n")) (defun mark-start () ;; copies latest mark to boo. copy and paste only to variable - new function write to buffer (interactive) (progn ;; goto end of buffer search back to equals and copy to last-in (switch-to-buffer-other-window "boo") (process-send-string "my-process" "pausing get_time_pos\n") (sleep-for 0.1) (goto-char (point-max)) (backward-char) (backward-char) (setq end (point)) (search-backward "=") ;; one char forward (forward-char) (setq start (point)) (copy-region-as-kill start end) (setq lastin (car kill-ring)) (switch-to-buffer-other-window "*GNEVE*"))) (defun mark-end () ;; copies latest mark to boo. copy and paste only to variable - new function write to buffer (interactive) (progn ;; goto end of buffer search back to equals and copy to last-in (switch-to-buffer-other-window "boo") (process-send-string "my-process" "pausing get_time_pos\n") (sleep-for 0.1) (goto-char (point-max)) (backward-char) (backward-char) (setq end (point)) (search-backward "=") ;; one char forward (forward-char) (setq start (point)) (copy-region-as-kill start end) (setq lastout (car kill-ring)) (switch-to-buffer-other-window "*GNEVE*")))
Also to be used as subtitle editor.
notes:
Creating an Asynchronous Process
Function: start-process name buffer-or-name program &rest args
This function creates a new asynchronous subprocess and starts the program program running in it. It returns a process object that stands for the new subprocess in Lisp. The argument name specifies the name for the process object; if a process with this name already exists, then name is modified (by adding `<1>', etc.) to be unique. The buffer buffer-or-name is the buffer to associate with the process.
buffer-or-name is of interest to try and receive timing information from mplayer slave:
references:
http://www.chemie.fu-berlin.de/chemnet/use/info/elisp/elisp_34.html