我试图用音频中出现的时间/地点的时间戳来标记转录文本的每个段落。
mplayer
并emacs
让我接近。 mplayer
,在终端中,输出一串合适的时间信息;例如。 (命令和示例日志)
mplayer au-file 1>event.log 2>&1
A: 0.8 (00.7) of 3207.0 (53:27.0) 0.1% [J
A: 0.9 (00.9) of 3207.0 (53:27.0) 0.1% [J
A: 1.0 (01.0) of 3207.0 (53:27.0) 0.1% [J
某些未绑定的键(例如,F12
)可用于标记日志中的事件 - 特别是段落的开头。
xdotool key --window $termID F12
A: 3.1 (03.0) of 3207.0 (53:27.0) 0.1% [J
No bind found for key 'F12'.
A: 3.2 (03.2) of 3207.0 (53:27.0) 0.1% [J
A: 3.3 (03.3) of 3207.0 (53:27.0) 0.1% [J
上面的效果很好。接下来需要的是要注入的行号event.log
。我可能会通过绑定一个键来读取当前位置并将其附加到日志中, emacs
从而从内部触发这两个事件。emacs
point
是的,你猜对了,我有一个问题。似乎mplayer
保留了一个流指针(或其他东西?),因为当它写入下一行时,它会覆盖我附加的文本。我不知道发生了什么,但我添加的行都没有出现在最终日志中......我已经使用了echo $number >>events.log
.
我通过查看日志 tail -f events.log
,它偶尔会显示我的一行,所以他们一定已经到了那里......
有办法解决这个问题吗?
要么通过一些fu
日志,要么采用完全不同的方法,例如。一些工具可以实时执行此操作。我研究过字幕工具和音频视频编辑器,但它们似乎太笨重了。我对任何想法持开放态度。
答案1
事实上,mplayer
它在文件中保留了自己的指针,因此它不会注意到何时echo
写入文件。当您有多个程序写入一个文件时,请安排所有这些程序打开该文件附加模式。在追加模式下,每次写入都发生在文件末尾。从外壳来看,那就是>>
。: >events.log
如果您想重新开始,请创建一个空文件,然后运行mplayer … >>events.log
。
请注意,虽然这保证了来自任一程序的每个字节都会出现在文件中,但原则上不能保证它们不会散布:理论上,echo hello >>events.log
可能会导致h
、 then 一些 mplayer 输出、 thene
等出现在文件。实际上,在大多数(如果不是全部)系统上,最多打印 512 字节的 echo 命令将最终形成一个片段。
答案2
笔记。这是我自己的问题的答案
下面的方法效果非常好。它向 mplayer 发送一系列未绑定的按键(mplayer 记录这些无效按键)。每个按下的键都被选择代表一位十进制数字,例如。发送F2 F5 F7
代表十进制数257
。发送 6 位数字大约需要 0.2 秒。时间戳是从第一次(标题)按键之前的日志行中获取的。这避免了与缓存延迟相关的所有问题,如中所述吉尔斯的回答。
emacs
只需将point
(光标)移动到另一行,或者按特定键(该代码不在这里,但我希望它足够简单(我是 elisp 的新手)),就可以非常轻松地运行它。这里是经过编码和 alpha 测试的解决方案...
# Insert a number (input to this script) into mplayer's log;
# Each digit of the input number is translated into
# a key-press for which mplayer does not have a binding.
# mplayer makes a log entry for each invalid key-press.
# The log entry identifies the key, so the entry can be
# translated back into its original decimal value
#
# A leading and a trailing marker are also sent to mplayer
#
# A simple parsing of the log can rebuild the original
# number and the time within the media stream when it occurred.
#
num=${1:-123456} # Default if for testing only
shopt -s extglob # For splitting the input number
# Window ID ($2) Defaults to win whose title == $USER@$HOSTNAME.*
win=${2:-$(($(wmctrl -l | sed -nr "s/^([^ ]+).* $USER@$HOSTNAME.*/\1/p")))}
# ========== ===== === # Key-press translation array
# 0123456789 begin end # decimal digits and delimiters
key=(F12 F{1..9} c \') # key names
# ========== ===== === #
xdotool key --window $win ${key[10]} # HEAD Marker
for i in ${num//?(.)/ } ;do
xdotool key --window $win ${key[i]} # Encoded decimal digit
done
xdotool type --window $win ${key[11]} # TAIL Marker
以下是提取时间戳和数字(行号或源文本中的字节/字符偏移量)的 3 步后续过程...
# (1) Each line of mplayer's normal output (vs errors) ends
# witn `\x1B\[J\x0D`. First, convertd this to `\n`
sed -nr 's/\x1B\[J\x0D/\n/gp' mplayer.log >/dev/null
# (2) The above pre-processing step(1) can be piped to the next sed step,
# but I've redirected it to /dev/nul for this example
# The following step works with a few lines of the pre-processed log
nbfk="No bind found for key"
sed -nr "
/^$nbfk 'c'\./,/^$nbfk '''\./{
/^$nbfk 'c'\./{g # HEAD Marker found
s/^A: *([0-9.]+).*/000000\1/
s/^0*([0-9]{6}\..*)/T:\1/p
}
s/^$nbfk 'F12'\..*/0/p # Digit
s/^$nbfk 'F([1-9])'\..*/\1/p # Digit
s/^$nbfk '''\..*/--/p # TAIL Marker found
}
h" <<'EOF'
A: 18.6 (18.6) of 3207.0 (53:27.0) 0.1%
A: 18.7 (18.6) of 3207.0 (53:27.0) 0.1%
No bind found for key 'c'.
A: 18.7 (18.6) of 3207.0 (53:27.0) 0.1%
No bind found for key 'F1'.
A: 18.7 (18.7) of 3207.0 (53:27.0) 1.0%
No bind found for key 'F2'.
A: 18.7 (18.7) of 3207.0 (53:27.0) 0.1%
A: 18.8 (18.7) of 3207.0 (53:27.0) 0.1%
No bind found for key 'F3'.
A: 18.8 (18.8) of 3207.0 (53:27.0) 0.1%
No bind found for key 'F4'.
A: 18.8 (18.8) of 3207.0 (53:27.0) 0.1%
No bind found for key 'F5'.
A: 18.9 (18.8) of 3207.0 (53:27.0) 0.1%
No bind found for key 'F6'.
A: 18.9 (18.8) of 3207.0 (53:27.0) 0.1%
No bind found for key '''.
A: 18.9 (18.9) of 3207.0 (53:27.0) 0.1%
A: 19.0 (18.9) of 3207.0 (53:27.0) 0.1%
EOF
# (3) The above step(2) can be piped to the next sed step,
# but I've let it go to stdout for this example
# The following example step works with output of step (2)
sed -nr "
/^T:[0-9.]+$/,/^--$/{
/^T:[0-9.]+$/{ s/^T:(.*)/\1 /; h}
/^[0-9]$/H
/^--$/{g; s/\n//g; p}
}" <<'EOF'
T:000018.7
1
2
3
4
5
6
--
EOF
这是最终输出: time in seconds
和测试line number
000018.7 123456