Reactでビデオ要素をキャプチャしてDBに保存する実装のメモ。
サーバサイドは/api/internal/register_imageのエンドポイントを作ってbinary型のカラムに保存できるようにしておく
フロント側の実装
video要素をcanvasに描画してそのままrequestで送れる。
const sample = () => { const videoCapture = () => { const canvas = document.getElementById('video-canvas'); const videoHeight = video.videoHeight; const videoWidth = video.videoWidth; canvas.height = videoHeight; canvas.width = videoWidth; canvas.getContext('2d').drawImage(video, 0, 0); const canvas_image = canvas.toDataURL('image/png'); axios.post( '/api/internal/register_image',{ headers: { 'content-type': 'multipart/form-data', }, image: image, } ); } return ( <video></video> <canvas id='video-canvas' hidden><canvus> <button onClick={videoCapture}>キャプチャする</button> ) }
こんな形式の値がpostされる。
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xuy9iZOt2VXdue98c8431CghkISMaSOMsY3H6Gg3NgaDcdvR0dER/RfbbcAYDBJSSfVevfll5svxzkPHb6297/0y65WqJAGtwmRFxsvKvPe733DOPuusvfbarfVqvY4vy1frzom+7cz5XTsi+JfXL6/i5vpVrJfnsV5No9XqRKvVisVyEa31Mq7O38T5yat49eyTePH0SQx7/Viv1/o7t6a1jlivV7FuraPX68VyuY7Vahk345sYjUbx7W//evzSL/+92Dk4jGjxgatoxSrWsdTP88U8FouF3sNXuxXR7XRivV7qPFarVbQ7bb231WpHSycdsVwto91uR7fbjU6np4vi7+v1IpbLeazWK72OY7U7Hf3Mefa6Pf3/StdfN4x/W9FucWP8tVrx+rWucbla6WfOh+9O18fk53Z+87Pf6JvO6/Uv3/xtnX9vrfWeTqcfwed1u9Fqc34+B73B7/Lx9E/+nmPynnY7gnuiB9mN1bqle1H/vx0F9T7+lsfP+6fjbL5aES3OIY+xrmO1dWzOvd1uNc9K1/5X/eVPqHuSn8aAa37Vff2rPpmf9vh12s0hd+s6bj+OT39cjQn+Ze7No617sY5VLGOxmsR8NY3ZfByL1SouLm/i//2vfxh/9Ad/HOPRNF6/fh3X1zcxmy2i3xtqXjFX+4Od2N8/1Lwfj2exWC41hJlL3U4vOp1uaNi1WrFcLmI+X8R0Oo35jHm7jm6rp/fyNZlMNHF2d3b1+n6fWBGxXK70nn5/EMvFMqbTmeZ9p9PRXGIuL+dzz3WN44jVgniw1rjr9brRbncUI3gNX/y+xXfOSeZoxZLlchmz2Uyftbe/p/csFkvNOz6Lr8FgoDlMHOt2iR+cJ8ePmM6mGnbElna7q3lR94HX9bpdvZ/jdns9xRXu12q50n2ZjCdxfn6+iRnEnOFgGMP+IHaGg+j2OjFfTmK1WsRitojDw8P4lV/9+/Huu+/G48eP4+TkJK6urmI0HuserloR07mfjeJUuxPtbkd/6/X7Opf9g8PY29+Pfq+va1EsXiz0LPg7r+VrOh7HarXWuXLPBsMd/b2nmLuKyWQco9GNrmExn8V0NtbvHPPnEe0lISu67XX0OxE7g07s9tv
- 表示側 サーバ側から上記の形式でデータを受け取ってそのままimgタグのsrcに指定して表示できる
const [images, setImages] = useState([]); useEffect(() => { async function fetchImages() { const images = await axios.get '/api/internal/images' ); setImages(images.data); } fetchImages(); }, []); return ( images.map((image, i) => ( <img src={image.image} key={i}</img> ) )
追記
DBに入れるとストレージ食うのでS3とかに入れた方がよかった。