LoginSignup
kuma0317
@kuma0317

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

動画撮影・録画アプリを作ったものの動画を再生することができない

解決したいこと

pythonで動画撮影・録画アプリを作っているのですが、得られた動画を開くことができません。

アプリの概要ですが、プログラムを回すと、まず「Camera On」「Camera Off」「Record」「RecordStop」のボタンがある「OpenCVによるカメラアプリ」ウインドウが現れます。

・「Camera On」を押すとカメラが動き、画面が表示されます。
・「Camera Off」を押すとプログラムがストップして画面が消えます。
・「Record」を押すとRecord Windowが現れ録画がスタートします。
・「RecordStop」を押すと録画が停止し、「Camera On」の状態に戻ります。

問題はRecordを押すと、ファイルは作られるものの、動画ファイルを開くことができないということです。

録画するときのコード

while True:
     # データ取得
      ret, frame = camera.read()
      # 日付を入れる
      font = cv2.FONT_HERSHEY_SIMPLEX
      cv2.putText(frame,strftime("%Y-%m-%d-%H:%M:%S"),(10,30), font, 1,(255,255,255),2,cv2.LINE_AA)

      cv2.imshow('Record Window', frame)
      video.write(frame)
      #RecordStopがTrueなら、録画を停止する
      event, values = window.read(timeout=20)
      if event == 'RecordStop':
          break

すべてのソースコードは以下のようになります。

import PySimpleGUI as sg
import cv2
import numpy as np
from time import strftime

windowname = "Camera View"

camera = cv2.VideoCapture(0)

# レイアウト(1行目:テキスト、2行目:映像画面、3行目:ボタン、ボタン、ボタン)
sg.theme('BluePurple')
layout = [[sg.Text('ビデオカメラの操作:'),sg.Text(size=(15,1), key='-OUTPUT-')],[sg.Button('CameraOn'), sg.Button('CameraOff'), sg.Button('Record'), sg.Button('RecordStop')]]


# ウィンドウの生成
window = sg.Window('OpenCVによるカメラアプリ',layout, location=(800, 400))

# 動画ファイル保存用の設定
fps = int(camera.get(cv2.CAP_PROP_FPS))                    # カメラのFPSを取得
w = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))              # カメラの横幅を取得
h = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))             # カメラの縦幅を取得
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')        # 動画保存時のfourcc設定(mp4用)
video = cv2.VideoWriter('video.mp4', fourcc, fps, (w, h))  # 動画の仕様(ファイル名、fourcc, FPS, サイズ)

CameraOn = False
Record = False

# イベントループ
while True:
    # イベント取得
    event, values = window.read(timeout=20)
    # 「CameraOn」ボタン押下時の処理
    #撮影を開始する
    if event == 'CameraOn':
        CameraOn = True
        Record = False

    # 「CameraOff」ボタン押下時の処理
    # 撮影を停止する
    elif event == 'CameraOff' or event == sg.WIN_CLOSED:
        CameraOn = False
        Record = False
        break
    
    # 「Record」ボタン押下時の処理
    # 録画を開始する
    elif event == 'Record':
        CameraOn = False
        Record = True
    
        
    # CameraOnがTrueなら、撮影を開始する
    elif CameraOn:
        # データ取得
        ret, frame = camera.read()
        frame_num = camera.get(cv2.CAP_PROP_FRAME_COUNT)

        # 日付を入れる
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(frame,strftime("%Y-%m-%d-%H:%M:%S"),(10,30), font, 1,(255,255,255),2,cv2.LINE_AA)
        
        # 表示
        cv2.imshow(windowname, frame)

    # RecordがTrueなら、録画を開始する
    elif Record:
        cv2.destroyWindow('Camera View')
        while True:
            # データ取得
            ret, frame = camera.read()
            # 日付を入れる
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(frame,strftime("%Y-%m-%d-%H:%M:%S"),(10,30), font, 1,(255,255,255),2,cv2.LINE_AA)
            # 表示
            cv2.imshow('Record Window', frame)
            video.write(frame)
            #RecordStopがTrueなら、録画を停止する
            event, values = window.read(timeout=20)
            if event == 'RecordStop':
                break
        cv2.destroyWindow('Record View')
        CameraOn = True
        Record = False


cv2.destroyAllWindows()
print("プログラムを終了します")

自分で試したこと

GUIを使わず、キー入力による操作では、録画および停止はできます。
おそらくボタンの表示画面が現れることが問題だと思っていますが、destrowWindow(window)を挿入しても問題は解決されませんでした。

0

1Answer

cv2.VideoWriterは録画終了時にreleaseメソッドを呼び出す必要があります。

録画終了時にreleaseメソッドを呼び出すように変更してみてください。

#RecordStopがTrueなら、録画を停止する
event, values = window.read(timeout=20)
if event == 'RecordStop':
    video.release()
    break
1

Comments

  1. @kuma0317

    Questioner
    ありがとうございます。これでうまくいきました。

Your answer might help someone💌