teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

訂正: seek 時のフラグの変更点について、情報を訂正

2021/07/11 09:24

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -6,9 +6,9 @@
6
6
   → bytes の場合は意味が変わってきます。フレームを正しく読み出せない位置へのseek
7
7
   → frame 単位のseekは出来ません。フレーム間圧縮等があると、デコードが出来ない。
8
8
   正しく読み出すには、必ず近くの keyframe から読み出しを開始する必要があります。
9
-  任意のフレームに移動したい場合は seek 後に自分で読み進める。(PyAV側では対応しない)
9
+  任意のフレームに移動したい場合は ~~seek 後に自分で読み進める。(PyAV側では対応しない)~~
10
-  → 参考にした情報が古くないかを確認。
11
-  time以外を指定する whence オプションは廃止になってます。
10
+  ~~time以外を指定する whence オプションは廃止になってます。~~
11
+  訂正: オプションの仕様が変更され any_frame オプションが有りました。
12
12
  - seek 後に demux/decode を呼び出す。(途中でseekは出来ない、理由は上述)
13
13
  - f.index は読み出し時の通し番号なので、seek 後の確認としては使えません。→ f.pts
14
14
 

2

補足

2021/07/11 09:24

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -21,6 +21,7 @@
21
21
  同一スレッド内で呼び出す方法は幾つか有ります。
22
22
  - 別スレッドからthreading.Eventでメインスレッドへ通知。
23
23
  - 毎ループ時間を確認する。`if pts * time_base > 20.0: seek ...`
24
+  → 事前にパケット単位で確認する等で、効率化は出来そう。
24
25
  - sched モジュールをノンブロッキングで使う。
25
26
 
26
27
  ## 2) Seek

1

検証に使ったコードを追記

2021/07/11 04:10

投稿

teamikl
teamikl

スコア8817

answer CHANGED
@@ -32,6 +32,33 @@
32
32
  [PyAV - time](https://pyav.org/docs/develop/api/time.html)
33
33
 
34
34
  ----
35
+ 検証用コード追記
36
+ ```python
37
+
38
+ def read_frame_until(timestamp):
39
+ for p in a.demux(video=0, audio=0):
40
+ if p.pts * p.time_base >= timestamp:
41
+ # XXX: packet の区切り位置の確認
42
+ # この条件で packet のループを抜けていいかどうかは未検証。
43
+ break
44
+ for f in p.decode():
45
+ if f.pts * p.time_base >= timestamp:
46
+ break
47
+ yield p, f
48
+
49
+ for p, f in read_frame_until(20):
50
+ print(f, f.pts * float(p.time_base)) # frame, 秒数を表示
51
+
52
+ # 00:00:10 直近の keyframe 迄 seek
53
+ print("SEEK 10")
54
+ a.seek(10 * av.time_base)
55
+
56
+ # keyframe 次第では、9秒付近から再開されることもある。
57
+ for p, f in read_frame_until(13):
58
+ print(f, f.pts * float(p.time_base)) # frame, 秒数を表示
59
+ ```
60
+
61
+ ----
35
62
  - [PyAV seek](https://github.com/PyAV-Org/PyAV/blob/9ac05d9ac902d71ecb2fe80f04dcae454008378c/av/container/input.pyx#L186)
36
63
 
37
64
  - [FFMpeg av_frame_seek](https://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#gaa23f7619d8d4ea0857065d9979c75ac8)