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

質問編集履歴

2

コードのミスを修正しました。

2021/07/05 03:06

投稿

harukat
harukat

スコア1

title CHANGED
File without changes
body CHANGED
@@ -87,7 +87,6 @@
87
87
 
88
88
 
89
89
  def gen():
90
- global browser
91
90
  """Video streaming generator function."""
92
91
  bw_flag = True
93
92
  # 白黒画像の切り替えを繰り返す
@@ -133,7 +132,7 @@
133
132
  <video id="player-canvas" controls autoplay loop muted poster="" playsinline width="1280px" height="720px"></video>
134
133
  <!-- jinja2のテンプレートの書き方です。/video_feedを呼び出しています。 -->
135
134
  <script type="text/javascript">
136
- function drawCanvasFromMjpegStrmer(){ //MJPG-streamer -> CANVAS-TAG
135
+ function drawCanvasFromMjpeg(){ //MJPG-streamer -> CANVAS-TAG
137
136
  const canvas = document.getElementById("canvas");
138
137
  const ctx = canvas.getContext("2d");
139
138
  setInterval(() => {
@@ -156,7 +155,7 @@
156
155
  canvasStream = canvas.captureStream(30);
157
156
  video.srcObject = canvasStream;
158
157
  }
159
- drawCanvasFromMjpegStrmer();
158
+ drawCanvasFromMjpeg();
160
159
  drawVideoFromCanvas();
161
160
  </script>
162
161
  </body>

1

Python サーバー部分に関して追記しました。

2021/07/05 03:06

投稿

harukat
harukat

スコア1

title CHANGED
@@ -1,1 +1,1 @@
1
- MJPG-streamer のストリーミング画像canvasStream を使って video タグに描画できな
1
+ Python の FastAPI で出力した MJPG-streamer を video タグに描画した
body CHANGED
@@ -1,20 +1,23 @@
1
- ### 前提・実現したいこと
1
+ # 前提・実現したいこと
2
2
  Javascript を使って、 MJPG-streamer のストリーミング画像をvideoタグに描画しようとしています。
3
3
  しかし、 Canvas には画像が出力され、動画のように更新されているものの、 video タグの方では表示されませんでした。
4
- captureStream() を使って video の srcObject とする正しい方法を教えていただけますと幸いです。
4
+ **captureStream()** を使って video の srcObject とする正しい方法を教えていただけますと幸いです。
5
5
 
6
6
  以下のリンクを参考に実装しました。
7
7
  [https://zenn.dev/zgw426/articles/ed632c88148183e9b902](https://zenn.dev/zgw426/articles/ed632c88148183e9b902)
8
8
  [https://qiita.com/akmtsyk/items/bb38947f028bf11fe72b](https://qiita.com/akmtsyk/items/bb38947f028bf11fe72b)
9
9
 
10
- ### 発生している問題・エラーメッセージ
10
+ # 発生している問題・エラーメッセージ
11
11
  console を確認したところ、エラーは発生していませんでした。
12
12
  video タグではローディングが続く状態です。
13
+
14
+
15
+ # 該当のソースコード
16
+ ##HTML側
17
+ 以下のコードで MJPEG を video タグに変換して表示させようと試みています。
13
18
  drawCanvasFromMjpegStrmer()はおそらく問題なく動作しており、 canvas タグは更新されています。
14
- ### 該当のソースコード
15
-
16
19
  ```HTML
17
- <!-- index.html -->
20
+ <!-- test.html -->
18
21
  <html>
19
22
  <head>
20
23
  <title>Video Streaming Demonstration</title>
@@ -56,13 +59,117 @@
56
59
  </html>
57
60
  ```
58
61
 
62
+ ###サーバー(Python)側
63
+ サーバーライブラリには、fastAPI を採用し、実装しています。
59
- ### 試したこと
64
+ ```Python
65
+ import sys
66
+ import uvicorn
60
67
 
68
+ from fastapi import FastAPI, Request
69
+ from fastapi.responses import HTMLResponse, StreamingResponse
70
+ from fastapi.staticfiles import StaticFiles
71
+ from fastapi.templating import Jinja2Templates
72
+
73
+ import numpy as np
74
+ import cv2
75
+ import time
76
+
77
+ app = FastAPI()
78
+
79
+ app.mount("/static", StaticFiles(directory="static"), name="static")
80
+ templates = Jinja2Templates(directory="templates")
81
+
82
+
83
+
84
+ @app.get("/", response_class=HTMLResponse)
85
+ async def index(request: Request):
86
+ return templates.TemplateResponse('index.html', {"request": request})
87
+
88
+
89
+ def gen():
90
+ global browser
91
+ """Video streaming generator function."""
92
+ bw_flag = True
93
+ # 白黒画像の切り替えを繰り返す
94
+ while True:
95
+ if bw_flag:
96
+ img = np.zeros((1280,720,3), dtype=np.uint8)
97
+ else:
98
+ img = np.ones((1280,720,3), dtype=np.uint8) * 255
99
+ if type(img) == np.ndarray:
100
+ frame = cv2.imencode('.jpg', img)[1].tobytes()
101
+ yield (b'--frame\r\n'
102
+ b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
103
+ else:
104
+ print("img is None.")
105
+ time.sleep(0.5)
106
+ bw_flag = not bw_flag # 白黒反転
107
+
108
+
109
+ @app.get('/video_feed', response_class=HTMLResponse)
110
+ async def video_feed():
111
+ """Video streaming route. Put this in the src attribute of an img tag."""
112
+ return StreamingResponse(gen(),
113
+ media_type='multipart/x-mixed-replace; boundary=frame')
114
+
115
+ def start_server():
116
+ uvicorn.run(app, host="0.0.0.0", port=8000)
117
+
118
+ if __name__ == "__main__":
119
+ start_server()
120
+ ```
121
+
122
+ 以下のコードは`templates/index.html`に配置し、`localhost:8000`でアクセスしたときに表示される画面です。
123
+ ```HTML
124
+ <!-- index.html -->
125
+ <html>
126
+ <head>
127
+ <title>Video Streaming Demonstration</title>
128
+ </head>
129
+ <body>
130
+ <h1>Video Streaming Demonstration</h1>
131
+ <!-- <img src="{{ url_for('video_feed') }}"> -->
132
+ <canvas id="canvas", width="1280px", height="720px"></canvas>
133
+ <video id="player-canvas" controls autoplay loop muted poster="" playsinline width="1280px" height="720px"></video>
134
+ <!-- jinja2のテンプレートの書き方です。/video_feedを呼び出しています。 -->
135
+ <script type="text/javascript">
136
+ function drawCanvasFromMjpegStrmer(){ //MJPG-streamer -> CANVAS-TAG
137
+ const canvas = document.getElementById("canvas");
138
+ const ctx = canvas.getContext("2d");
139
+ setInterval(() => {
140
+ if (canvas && ctx){
141
+ const chara = new Image();
142
+ chara.src = "{{ url_for('video_feed') }}" // URLをfastapiから取得(localhost:8000/video_feed)
143
+ chara.onload = () => {
144
+ ctx.drawImage(chara, 0, 0);
145
+ };
146
+ }
147
+ }, 10000/60);
148
+ }
149
+
150
+ function drawVideoFromCanvas() { // CANVAS-TAG -> VIDEO-TAG
151
+ const canvas = document.getElementById("canvas");
152
+ const video = document.getElementById("player-canvas");
153
+ const ctx = canvas.getContext('2d');
154
+
155
+ // ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
156
+ canvasStream = canvas.captureStream(30);
157
+ video.srcObject = canvasStream;
158
+ }
159
+ drawCanvasFromMjpegStrmer();
160
+ drawVideoFromCanvas();
161
+ </script>
162
+ </body>
163
+ </html>
164
+ ```
165
+ # 試したこと
166
+
61
167
  ブラウザの問題かと思い、 Firefox で試しましたが、動作しませんでした。
62
- **Fastapi を用いたローカルサーバー上のページを Chrome で開くと、 video タグ側でも表示されました。**
168
+ **Fastapi を用いたローカルサーバー上のページ(`localhost:8000`)を Chrome で開くと、 video タグ側でも表示されました。**
63
-
169
+ `test.html`を直に開くと canvas のみ動画が表示されました。
64
170
  ### 補足情報(FW/ツールのバージョンなど)
65
171
  OS: Linux (OpenSUSE Leap 15.3)
172
+ Python: 3.8.10(Pyenv)
66
173
  ブラウザ:
67
174
  - Google Chrome Stable: ver. 91.0.4472
68
175
  - Firefox: ver. 78.11.0