[新插件] org-media-note 为视频和音频做交互笔记 (新支持在线视频)

似乎是因为 (org-attach-dir) 返回为 nil, 导致(org-media-note--media-files-in-dir attach-dir) 报错Wrong type argument: stringp, nil

修改成这样就没问题了

(defun org-media-note-mpv-smart-play ()
  "Conditionally open media file in mpv.
1. With a single attachment, file, or url: play it in mpv;
2. With multiple attachments, open the attach dir to select;
3. Else, answer y to find local file to open, n to input URL."
  (interactive)
  (let* ((key (org-media-note--current-org-ref-key))
         (media-file-by-key (org-media-note-get-media-file-by-key key))
         (media-url-by-key (org-media-note-get-url-by-key key))
         (attach-dir (if (org-attach-dir)
                         (format "%s/"
                                 (org-attach-dir))))
         )
    (cond
     ((and (org-media-note-ref-cite-p)
           media-file-by-key)
      (mpv-play media-file-by-key))
     ((and (org-media-note-ref-cite-p)
           media-url-by-key)
      (org-media-note--mpv-play-online-video media-url-by-key))
     (attach-dir
      (let* ((media-files-in-attach-dir (org-media-note--media-files-in-dir attach-dir))
             (number-of-media-files (length media-files-in-attach-dir)))
       (if (= 1 number-of-media-files)
          (mpv-play (car media-files-in-attach-dir))
        (mpv-play (read-file-name "File to play: " attach-dir))) ))
     (t
      (if (y-or-n-p "Local media (`n` to enter remote URL)? ")
          (mpv-play (read-file-name "File to play: "))
        (org-media-note-play-online-video))))))

今天学习使用了你开发的插件,感谢。

关于 mpv 打开需要代理的 YouTube 视频,使用类似 clash TUN 模式的代理软件可以正常使用。

hi 您读PDF文稿或其它文稿时有没有这样一套交互笔记流程

楼主有另一个包就是处理pdf的 [新插件] org-noter-plus 提取PDF或EPUB文档的大纲及笔记 - #15,来自 hongfei6

1 个赞

谢谢你。我看看 :grinning:

你好,我通过 quelpa 在今天安装了插件,可依然有这个问题……麻烦问下是什么问题?

先用的 (require 'org-attach) 临时处理了下。

謝謝楼主,这个插件好!

我用来听音频课,发现播放音频时mpv没有界面,不能快速定位。这个插件的快进键一次只能快进5秒,能不能增加一个「一次快进百分之十」的按键。

谢谢!

还有一个问题,有无方法设置默认打开本地文件,而不是询问打开本地还是网址?谢谢

最近想对一些b站的视频做笔记,但是打开在线视频没反应,找了一下解决方法,可能是需要对 mpv 做一些配置:

referrer=https://www.bilibili.com

为了获取更清晰的视频:

ytdl-raw-options=cookies-from-browser=[chrome]

另外我使用的是 yt-dlp:

script-opts-append=ytdl_hook-ytdl_path=/usr/bin/yt-dlp
1 个赞

感谢!很实用的插件。

请教如何做到为不同的文档中的截图设置不同的目录?

例如我在编辑 a.org的时候的截图,希望存储到media_imgs/a/screenshot.png

我在使用org-download的时候发现Syntax to create subdirectories for each org file: (setq-default org-download-image-dir "./img/?") · Issue #195 · abo-abo/org-download · GitHub 的讨论,可以实现这个功能。

org-download的选项有三个Directory, attach, Custom Functionorg-media-note/org-media-note-core.el at dd458c3260530d1866eaa0cde4b1bb71c6f8cf0e · yuchen-lea/org-media-note · GitHub

org-media-note只有两个:org-media-note/org-media-note-core.el at dd458c3260530d1866eaa0cde4b1bb71c6f8cf0e · yuchen-lea/org-media-note · GitHub

再次感谢!

首先感谢开发者弥补了 Org-mode 音视频笔记的短板,不过好像不能很好地处理本地的带空格或是[]等需要转义字符\的文件路径?

请问能打开视频文件但报错不能进行后面的操作是什么问题?

Debugger entered--Lisp error: (error "‘get_property’ failed: property unavailable")
  signal(error ("‘get_property’ failed: property unavailable"))
  error("`%s' failed: %s" "get_property" "property unavailable")
  (if (string-equal status "success") nil (error "`%s' failed: %s" command status))
  (let* ((response (catch '--cl-block-mpv-run-command-wait-for-response-- (mpv--enqueue (cons command arguments) #'(lambda (response) (throw ... response))) (while (mpv-live-p) (sleep-for 0.05)))) (status (alist-get 'error response)) (data (alist-get 'data response))) (if (string-equal status "success") nil (error "`%s' failed: %s" command status)) data)
  (progn (let* ((response (catch '--cl-block-mpv-run-command-wait-for-response-- (mpv--enqueue (cons command arguments) #'(lambda ... ...)) (while (mpv-live-p) (sleep-for 0.05)))) (status (alist-get 'error response)) (data (alist-get 'data response))) (if (string-equal status "success") nil (error "`%s' failed: %s" command status)) data))
  (if (mpv-live-p) (progn (let* ((response (catch '--cl-block-mpv-run-command-wait-for-response-- (mpv--enqueue (cons command arguments) #'...) (while (mpv-live-p) (sleep-for 0.05)))) (status (alist-get 'error response)) (data (alist-get 'data response))) (if (string-equal status "success") nil (error "`%s' failed: %s" command status)) data)))
  mpv-run-command("get_property" "path")
  mpv-get-property("path")
  (let ((file-path (mpv-get-property "path")) (ref-key (org-media-note--current-org-ref-key)) (icon (if (featurep 'all-the-icons) (all-the-icons-material "ondemand_video") "")) speed current-timestamp total-timestamp remaining-hms bib-entry title) (if file-path (progn (setq speed (mpv-get-property "speed")) (setq volume (mpv-get-property "volume")) (setq current-timestamp (org-media-note--get-current-timestamp)) (setq total-timestamp (org-media-note--get-duration-timestamp)) (setq remaining-hms (org-media-note--seconds-to-timestamp (mpv-get-property "playtime-remaining"))) (s-concat icon " org-media-note: " current-timestamp " / " total-timestamp "\11 Volume: " (number-to-string volume) "\11 Speed: " (number-to-string speed) "\11 Remaining: " remaining-hms "\n\11❯ " (if (org-media-note-ref-cite-p) (progn (setq bib-entry (bibtex-completion-get-entry ref-key)) (setq title (bibtex-completion-get-value "title" bib-entry)) (format "%s (%s)" title ref-key)) (if (org-media-note--online-video-p file-path) (format "%s (%s)" (mpv-get-property "media-title") file-path) file-path)))) (concat icon " org-media-note")))
  org-media-note--hydra-title()
  (format "\n %s\n\n File                      Playback         ..." (org-media-note--hydra-title) #("o" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (if (org-media-note-ref-cite-p) (format "Open %s" (org-media-note--current-org-ref-key)) "Open file") 21) #("<SPC>" 0 5 (face hydra-face-red)) #("+" 0 1 (face hydra-face-red)) #("i" 0 1 (face hydra-face-red)) #("I p" 0 3 (face hydra-face-red)) #("t m" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto insert media item" (bound-and-true-p org-media-note-mode)) #("j" 0 1 (face hydra-face-red)) #("l" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (let ((time-a (mpv-get-property "ab-loop-a")) (time-b (mpv-get-property "ab-loop-b"))) (if (org-media-note--ab-loop-p) (format "Clear A-B loop (%s - %s)" (org-media-note--seconds-to-timestamp time-a) (org-media-note--seconds-to-timestamp time-b)) (if (numberp time-a) (format "Set B of A-B loop (%s - )" (org-media-note--seconds-to-timestamp time-a)) "Set A of A-B loop"))) 46) #("-" 0 1 (face hydra-face-red)) #("a" 0 1 (face hydra-face-red)) #("I n" 0 3 (face hydra-face-red)) #("t c" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Use ref key instead of absolute path" (bound-and-true-p org-media-note-use-refcite-first)) #("T" 0 1 (face hydra-face-red)) #("g" 0 1 (face hydra-face-red)) #("0" 0 1 (face hydra-face-red)) #("S" 0 1 (face hydra-face-red)) #("I t" 0 3 (face hydra-face-red)) #("t p" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Pause media after insert link" (bound-and-true-p org-media-note-pause-after-insert-link)) #("c" 0 1 (face hydra-face-red)) #("<left>" 0 6 (face hydra-face-red)) #("m" 0 1 (face hydra-face-red)) #("s" 0 1 (face hydra-face-red)) #("I s" 0 3 (face hydra-face-red)) #("t s" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto save screenshot" (bound-and-true-p org-media-note-save-screenshot-p)) #("x" 0 1 (face hydra-face-red)) #("<right>" 0 7 (face hydra-face-red)) #("H-m" 0 3 (face hydra-face-red)) #("t S" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Screenshot with subtitles" (bound-and-true-p org-media-note-screenshot-with-sub)) #("z" 0 1 (face hydra-face-red)) #("C-<left>" 0 8 (face hydra-face-red)) #("t t" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Timestamp format: %s" (cond ((eq org-media-note-timestamp-pattern 'hms) "hh:mm:ss") ((eq org-media-note-timestamp-pattern 'hmsf) "hh:mm:ss.fff"))) 41) #("C-<right>" 0 9 (face hydra-face-red)) #("t M" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Separator when merge: %s" org-media-note-separator-when-merge) 41))
  eval((format "\n %s\n\n File                      Playback         ..." (org-media-note--hydra-title) #("o" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (if (org-media-note-ref-cite-p) (format "Open %s" (org-media-note--current-org-ref-key)) "Open file") 21) #("<SPC>" 0 5 (face hydra-face-red)) #("+" 0 1 (face hydra-face-red)) #("i" 0 1 (face hydra-face-red)) #("I p" 0 3 (face hydra-face-red)) #("t m" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto insert media item" (bound-and-true-p org-media-note-mode)) #("j" 0 1 (face hydra-face-red)) #("l" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (let ((time-a (mpv-get-property "ab-loop-a")) (time-b (mpv-get-property "ab-loop-b"))) (if (org-media-note--ab-loop-p) (format "Clear A-B loop (%s - %s)" (org-media-note--seconds-to-timestamp time-a) (org-media-note--seconds-to-timestamp time-b)) (if (numberp time-a) (format "Set B of A-B loop (%s - )" (org-media-note--seconds-to-timestamp time-a)) "Set A of A-B loop"))) 46) #("-" 0 1 (face hydra-face-red)) #("a" 0 1 (face hydra-face-red)) #("I n" 0 3 (face hydra-face-red)) #("t c" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Use ref key instead of absolute path" (bound-and-true-p org-media-note-use-refcite-first)) #("T" 0 1 (face hydra-face-red)) #("g" 0 1 (face hydra-face-red)) #("0" 0 1 (face hydra-face-red)) #("S" 0 1 (face hydra-face-red)) #("I t" 0 3 (face hydra-face-red)) #("t p" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Pause media after insert link" (bound-and-true-p org-media-note-pause-after-insert-link)) #("c" 0 1 (face hydra-face-red)) #("<left>" 0 6 (face hydra-face-red)) #("m" 0 1 (face hydra-face-red)) #("s" 0 1 (face hydra-face-red)) #("I s" 0 3 (face hydra-face-red)) #("t s" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto save screenshot" (bound-and-true-p org-media-note-save-screenshot-p)) #("x" 0 1 (face hydra-face-red)) #("<right>" 0 7 (face hydra-face-red)) #("H-m" 0 3 (face hydra-face-red)) #("t S" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Screenshot with subtitles" (bound-and-true-p org-media-note-screenshot-with-sub)) #("z" 0 1 (face hydra-face-red)) #("C-<left>" 0 8 (face hydra-face-red)) #("t t" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Timestamp format: %s" (cond ((eq org-media-note-timestamp-pattern 'hms) "hh:mm:ss") ((eq org-media-note-timestamp-pattern 'hmsf) "hh:mm:ss.fff"))) 41) #("C-<right>" 0 9 (face hydra-face-red)) #("t M" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Separator when merge: %s" org-media-note-separator-when-merge) 41)))
  hydra-show-hint((format "\n %s\n\n File                      Playback         ..." (org-media-note--hydra-title) #("o" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (if (org-media-note-ref-cite-p) (format "Open %s" (org-media-note--current-org-ref-key)) "Open file") 21) #("<SPC>" 0 5 (face hydra-face-red)) #("+" 0 1 (face hydra-face-red)) #("i" 0 1 (face hydra-face-red)) #("I p" 0 3 (face hydra-face-red)) #("t m" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto insert media item" (bound-and-true-p org-media-note-mode)) #("j" 0 1 (face hydra-face-red)) #("l" 0 1 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (let ((time-a (mpv-get-property "ab-loop-a")) (time-b (mpv-get-property "ab-loop-b"))) (if (org-media-note--ab-loop-p) (format "Clear A-B loop (%s - %s)" (org-media-note--seconds-to-timestamp time-a) (org-media-note--seconds-to-timestamp time-b)) (if (numberp time-a) (format "Set B of A-B loop (%s - )" (org-media-note--seconds-to-timestamp time-a)) "Set A of A-B loop"))) 46) #("-" 0 1 (face hydra-face-red)) #("a" 0 1 (face hydra-face-red)) #("I n" 0 3 (face hydra-face-red)) #("t c" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Use ref key instead of absolute path" (bound-and-true-p org-media-note-use-refcite-first)) #("T" 0 1 (face hydra-face-red)) #("g" 0 1 (face hydra-face-red)) #("0" 0 1 (face hydra-face-red)) #("S" 0 1 (face hydra-face-red)) #("I t" 0 3 (face hydra-face-red)) #("t p" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Pause media after insert link" (bound-and-true-p org-media-note-pause-after-insert-link)) #("c" 0 1 (face hydra-face-red)) #("<left>" 0 6 (face hydra-face-red)) #("m" 0 1 (face hydra-face-red)) #("s" 0 1 (face hydra-face-red)) #("I s" 0 3 (face hydra-face-red)) #("t s" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Auto save screenshot" (bound-and-true-p org-media-note-save-screenshot-p)) #("x" 0 1 (face hydra-face-red)) #("<right>" 0 7 (face hydra-face-red)) #("H-m" 0 3 (face hydra-face-red)) #("t S" 0 3 (face hydra-face-red)) (pretty-hydra-toggle "Screenshot with subtitles" (bound-and-true-p org-media-note-screenshot-with-sub)) #("z" 0 1 (face hydra-face-red)) #("C-<left>" 0 8 (face hydra-face-red)) #("t t" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Timestamp format: %s" (cond ((eq org-media-note-timestamp-pattern 'hms) "hh:mm:ss") ((eq org-media-note-timestamp-pattern 'hmsf) "hh:mm:ss.fff"))) 41) #("C-<right>" 0 9 (face hydra-face-red)) #("t M" 0 3 (face hydra-face-red)) (pretty-hydra--pad-or-trunc-hint (format "Separator when merge: %s" org-media-note-separator-when-merge) 41)) org-media-note-hydra)
  org-media-note-hydra/org-media-note-mpv-smart-play()
  funcall-interactively(org-media-note-hydra/org-media-note-mpv-smart-play)
  call-interactively(org-media-note-hydra/org-media-note-mpv-smart-play nil nil)
  command-execute(org-media-note-hydra/org-media-note-mpv-smart-play)

  • 空格是可以正常处理的
  • []的问题是与org-mode链接的语法冲突了

可以和mpvi相互参考下

感觉这个包更关注视频播放(播放列表、视频下载),org-media-note会更关注笔记功能。

OCR功能之前考虑过,但是没太想好怎么能不打断笔记记录的连贯性来ocr,以及我看的大都有字幕,自己不太需要,也没人提这个需求,就放着了。

配置好mpv,org-media-note也是可以播放bilibili加载弹幕等,

有时间再体验一下mpvi,光看文字说明不太能get到。

done: allow custom function for screenshot dir · yuchen-lea/org-media-note@9b5e91c · GitHub

自定义 org-media-note-screenshot-save-method

这个报错在我这边不会影响实际功能,就一直没有管它。最近刚确认了报错原因,已经修复。

done:

现在支持自定义step,支持设置秒、百分比、帧。

新需求建议提到github,我在github比论坛会更勤快点 :joy:

请问 org-media-note-mpv-general-options 的用法是:

(add-to-list 'org-media-note-mpv-general-options "autofit=50%")

是不是我写错了(真小白),所以没有生效,谢谢!(我很喜欢这个插件,本来对 org-mode 意兴阑珊,现在又重新回来了 :rofl:

My honor. 我也觉得这是目前做视频笔记最方便的方案 :sunglasses:

之前的Readme写得不对(现已改正),命令行参数需要有 -- 前缀

(add-to-list 'org-media-note-mpv-general-options "--autofit=50%")
1 个赞