首页 > 其他分享 >34. 媒体录制

34. 媒体录制

时间:2025-01-22 19:11:15浏览次数:1  
标签:视频 None QCamera 媒体 self 录制 34 获取 camera

一、多媒体设备

  多媒体设备是指本机中的音频输入设备(如麦克风)、音频输出设备(如音箱、头戴耳机)和视频输入设备(如摄像头)。多媒体设备通过 QMediaDevices 类提供的方法来获取,音频输入输出设备类是 QAudioDevice,视频输入设备类是 QCameraDevice。

  我们可以在终端中使用 pip 安装 pyside6 模块。

pip install pyside6

  用 QMediaDevices、QAudioDevice 和 QCameraDevice 创建设备实例的方法如下所示。

QMediaDevices(parent:QObject=None)
QAudioDevice()
QCameraDevice()

  QMediaDevices 类的常用方法如下:

# 静态方法
audioInputs() -> List[QAudioDevice]             # 获取音频输入设备
defaultAudioInput() -> QAudioDevice             # 获取默认音频输入设备

audioOutputs() -> List[QAudioDevice]            # 获取音频输出设备
defaultAudioOutput() -> QAudioDevice            # 获取默认音频输出设备

videoInputs() -> List[QCameraDevice]            # 获取视频输入设备
defaultVideoInput() -> QCameraDevice            # 获取默认的视频输入设备

  QMediaDevices 类的信号方法如下:

audioInputsChanged()            # 当音频输入设备发生改变时发射信号
audioOutputsChanged()           # 当音频输出设备发生改变时发射信号
videoInputsChanged()            # 当视频输入设备发生改变时发射信号

  QAudioDevice 类的常用方法如下:

description() -> str                                            # 获取音频设备的信息
id() -> QQByteArray                                             # 获取音频设备的识别号
isDefault() -> bool                                             # 获取是否是默认的音频设备
isFormatSupported(format:QAudioFormat) -> bool                  # 获取音频设备是否支持某种音频格式
isNull() -> bool                                                # 获取设备是否有效
minimumChannelCount() -> int                                    # 获取音频设备支持的最小通道数
maximumChannelCount() -> int                                    # 获取音频设备支持的最大通道数
minimumSampleRate() -> int                                      # 获取音频设备支持的最小采样率
maximumSampleRate() -> int                                      # 获取音频设备支持的最大采样率
mode() -> QAudioDevice.Mode                                     # 获取音频设备是输入还是输出设备
preferredFormat() -> QAudioFormat                               # 获取音频设备的默认音频格式
supportedSampleFormats() -> List[QAudioFormat.SampleFormat]     # 获取音频设备支持的采样格式

  mode() 的方法获取音频设备是输入还是输出设备,返回值是 QAudioDevice.Mode 枚举值,返回的值可以是:

QAudioDevice.Mode.Null          # 无效设备
QAudioDevice.Mode.Input         # 输入设备
QAudioDevice.Mode.Output        # 输出设备

  supportedSampleFormats() 方法获取音频设备支持的采样格式,返回值是 QAudioFormat.SampleFormat 的列表,QAudioFormat.SampleFormat 枚举值如下:

QAudioFormat.SampleFormat.UInt8
QAudioFormat.SampleFormat.Int16
QAudioFormat.SampleFormat.Int32
QAudioFormat.SampleFormat.Float
QAudioFormat.SampleFormat.Unknown

  QCameraDevice 类的常用方法如下:

description() -> str                                            # 获取视频输入设备的信息
id() -> QQByteArray                                             # 获取视频输入设备的识别号
isDefault() -> bool                                             # 获取是否是默认的视频输入设备
isNull() -> bool                                                # 获取视频输入设备是否有效
photoResolutions() -> List[QSize]                               # 获取视频输入设备的分辨率
position() -> QCameraDevice.Position                            # 获取视频输入的位置
videoFormats() -> List[QCameraFormat]                           # 获取视频输入设备支持的格式

  position() 方法获取视频输入的位置,返回值是 QCameraDevice.Position 枚举值,返回值可以是:

QCameraDevice.Position.BackFace                 # 后置摄像头
QCameraDevice.Position.FrontFace                # 前置摄像头
QCameraDevice.Position.UnspecifiedPosition      # 位置不确定

二、音频接口与视频接口

  要录制音频和视频,需要定义音频设备的接口 QAudioInput 和视频设备的接口 QCamera 后,才能调用音频设备和视频设备进行录制,QAudioInput 和 QCamera 相当于音频和视频输入通道。QAudioInput 是机器上的音频输入,例如内置麦克风或头戴麦克风,而 QCamera 是机器上的摄像头或外接相机。

  利用 QAudioInput 和 QCamera 创建音频设备和视频设备接口的方法如下所示。

QAudioInput(parent:QObject=None)
QAudioInput(deviceInfo:QAudioDevice, parent:QObject=None)

QCamera(parent:QObject=None)
QCamera(position:QCameraDevice.Position, parent:QObject=None)

2.1、音频接口

  音频接口 QAudioInput 类的常用方法如下:

# 实例方法
device() -> QAudioDeicve                            # 获取音频设备
isMuted() -> bool                                   # 获取是否静音
volume() -> bool                                    # 获取音量

# 槽函数
setDevice(device:QAudioDevice) -> None              # 设置音频设备
setMuted(muted:bool) -> None                        # 设置是否静音
setVolume(volume:float) -> float                    # 设置音量

  音频接口 QAudioInput 类的常用信号如下:

deviceChanged()                 # 当设备发生改变时发射信号
mutedChanged(muted:bool)        # 当静音状态发生改变时发射信号
volumeChanged(volume:float)     # 当音量发生改变时发射信号

2.2、视频接口

  视频接口 QCamera 类的常用方法如下:

# 实例方法
setCameraDevice(cameraDevice:QCameraaDevice) -> None                # 设置视频设备
cameraDevice() -> QCameraDevice                                     # 获取视频设备

isActive() -> bool                                                  # 获取相机是否启用
isAvailable() -> bool                                               # 获取相机是否可用

setCameraFormat(format:QCameraFormat) -> None                       # 设置视频格式
captureSession() -> QMediaCaptureSession                            # 获取与QCamera关联的媒体捕获器
supportedFeatures() -> QCamera.Features                             # 获取支持的特征

isExposureModeSupported(mode:QCamera.ExposureMode) -> None          # 获取是否支持某种曝光
exposureTime() -> float                                             # 获取曝光时间
manualExposureTime() -> float -> float                              # 获取自定义曝光时间
isoSensitivity() -> int                                             # 获取光敏感值
exposureCompensation() -> float                                     # 获取曝光补偿(EV值)  

flashMode() -> QCamera.FlashMode                                    # 获取快闪模式
isFlashModeSupported(mode:QCamera.FlashMode) -> bool                # 获取是否支持某种快闪模式
isFlashReady() -> bool                                              # 获取是否可以用快闪

setFocusMode(mode:QCamera.FocusMode) -> None                        # 设置对焦模式
isFlashModeSupported(mode:QCamera.FocusMode) -> bool                # 获取是否支持某种焦点模式
setFocusDistance(d:float) -> None                                   # 设置自定义焦距,0表示最近的点,1表示无限远
focusDistance() -> float                                            # 获取自定义焦距
setCustomFocusPoint(point:Union[QPoint, QPointF]) -> None           # 设置自定义焦点位置
customFocusPoint() -> QPointF                                       # 获取自定义焦点
focusPoint() -> QPointF                                             # 获取焦点

torchMode() -> QCamera.TorchMode                                    # 获取辅助光源模式
isTorchModeSupported(mode:QCamera.TorchMode) -> bool                # 获取是否支持某种辅助光源模式

whiteBalanceMode() -> QCamera.WhiteBalanceMode                      # 获取白平衡模式  
isWhiteBalanceModeSupported(mode:QCamera.WhiteBalanceMode) -> bool  # 获取是否支持某种白平衡模式 

colorTemperature() -> int                                           # 获取颜色温度

setZoomFactor(factor:float) -> None                                 # 设置缩放系数
zoomFactor() -> float                                               # 获取缩放系数

minimumExposureTime() -> float                                      # 获取最小的曝光时间
maximumExposureTime() -> float                                      # 获取最大的曝光时间

minimumIsoSensitivity() -> int                                      # 获取最小的光敏感值
maximumIsoSensitivity() -> int                                      # 获取最大的光敏感值

minimumZoomFactor() -> float                                        # 获取最小的方法系数
maximumZoomFactor() -> float                                        # 获取最大的放大系数

error() -> QCamera.Error                                            # 获取出错类型
errorString() -> str                                                # 获取出错信息

# 槽函数
start() -> None                                                     # 开启相机
stop() -> None                                                      # 关闭相机
setActive(active:bool) -> None                                      # 获取相机是否启用

setExposureMode(mode:QCamera.ExposureMode) -> None                  # 设置曝光模式
setAutoExposureTime() -> None                                       # 打开自动计算曝光时间
setManualExposureTime(seconds:float) -> None                        # 设置曝光时间
setAutoIsoSensitivity() -> None                                     # 根据曝光值开启自动选择光敏感值
setExposureCompensation(ev:float) -> None                           # 设置曝光补偿(EV值)

setFlashMode(mode:QCamera.FlashMode) -> bool                        # 设置是否可以用快闪
setTorchMode(mode:QCamera.TorchMode) -> None                        # 设置辅助光源模式
setWhiteBalanceMode(mode:QCamera.WhiteBalanceMode) -> None          # 设置白平衡模式

setColorTemperature(colorTemperature:int) -> None                   # 设置颜色温度

zoomTo(zoom:float, rate:float) -> None                              # 根据速率设置缩放系数

  用 setCameraDevice(cameraDevice:QCameraDevice) 方法为视频接口设置视频设备;用 start() 方法或 setActive(true) 方法开启视频设备;用 stop() 方法或 setActive(false) 方法停止视频设备。

  用 supportedFeatures() 方法获取相机支持的特征,返回值如下所示。

QCamera.Feature.ColorTemperature            # 相机支持色温
QCamera.Feature.ExposureCompensation        # 相机支持补偿曝光
QCamera.Feature.IsoSensitivity              # 相机支持自定义敏感值
QCamera.Feature.ManualExposureTime          # 相机支持自定义曝光时间
QCamera.Feature.CustomFocusPoint            # 相机支持自定义焦点
QCamera.Feature.FocusDistance               # 相机支持自定义焦距

  用 setExposureMode(mode:QCamera.ExposureMode) 方法设置相机的曝光模式,参数 mode 的取值是 QCamera.ExposureMode 的枚举值,可取的值如下所示;

QCamera.ExposureMode.ExposureAuto               # 自动
QCamera.ExposureMode.ExposureManual             # 手动
QCamera.ExposureMode.ExposurePortrait           # 人物
QCamera.ExposureMode.ExposureNight              # 夜晚
QCamera.ExposureMode.ExposureSports             # 运动
QCamera.ExposureMode.ExposureSnow               # 雪景
QCamera.ExposureMode.ExposureBeach              # 海景
QCamera.ExposureMode.ExposureAction             # 动作
QCamera.ExposureMode.ExposureLandscape          # 风景
QCamera.ExposureMode.ExposureNightPortrait      # 夜晚
QCamera.ExposureMode.ExposureTheatre            # 剧院
QCamera.ExposureMode.ExposureSunset             # 傍晚
QCamera.ExposureMode.ExposureSteadyPhoto        # 固定
QCamera.ExposureMode.ExposureFireworks          # 火景
QCamera.ExposureMode.ExposureParty              # 宴会
QCamera.ExposureMode.ExposureCandlelight        # 烛光
QCamera.ExposureMode.ExposureBarcode            # 条码

  用 setFlashMode(mode:QCamera.FlashMode) 方法设置相机的快闪模式,参数 mode 的取值是 QCamera.FlashMode 的枚举值,可取值如下:

QCamera.FlashMode.FlashOff
QCamera.FlashMode.FlashOn
QCamera.FlashMode.FlashAuto

  用 setFocusMode(mode:QCamera.FocusMode) 方法设置对焦模式,参数 mode 的取值是 QCamera.FocusMode 的枚举值,可取的值如下所示。

QCamera.FocusMode.FocusModeAuto             # 连续自动对焦模式
QCamera.FocusMode.FocusModeAutoNear         # 对近处物体连续自动对焦模式
QCamera.FocusMode.FocusModeAutoFar          # 对远处物体连续自动对焦模式
QCamera.FocusMode.FocusModeHyperfocal       # 对超过焦距范围的物体采用最大景深值
QCamera.FocusMode.FocusModeInfinity         # 对无限远对焦模式
QCamera.FocusMode.FocusModeManual           # 手动或固定对焦模式

  用 setTorchMode(mode:QCamera.TorchMode) 方法设置辅助光源模式,在光线不强时可以设置该模式,并会覆盖快闪模式,参数 mode 可取值如下:

QCamera.TorchMode.TorchOff
QCamera.TorchMode.TorchOn
QCamera.TorchMode.TorchAuto

  用 setWhiteBalanceMode(mode:QCamera.WhiteBalanceMode) 方法设置白平衡模式,白平衡是描述红、绿、蓝三基色混合生成后白色精确度的一项指标。在房间里的日光灯下拍摄的影像会显得发绿,在室内钨丝灯光下拍摄出来的景物会偏黄,而在日光阴影处拍摄到的照片则偏蓝,白平衡的作用是不管在任何光源下都能将白色物体还原为白色。参数 mode 是 QCamera.WhiteBalanceMode 的枚举值,可取的值如下所示。

QCamera.WhiteBalanceMode.WhiteBalanceAuto           # 自动
QCamera.WhiteBalanceMode.WhiteBalanceManual         # 手动
QCamera.WhiteBalanceMode.WhiteBalanceShade          # 阴影
QCamera.WhiteBalanceMode.WhiteBalanceTungsten       # 钨灯
QCamera.WhiteBalanceMode.WhiteBalanceFluorescent    # 荧光灯
QCamera.WhiteBalanceMode.WhiteBalanceSunlight       # 阳光
QCamera.WhiteBalanceMode.WhiteBalanceCloudy         # 云
QCamera.WhiteBalanceMode.WhiteBalanceFlash          # 快闪
QCamera.WhiteBalanceMode.WhiteBalanceSunset         # 日落

  在手动模式下,需要用 setColorTemperature(colorTemperature:int) 方法设置色温。

  视频接口 QCamera 类的常用信号如下:

activeChanged(arg__1:bool)                              # 照相机启动或停止时发射信号
cameraDeviceChanged()                                   # 照相设备发生改变时发射信号
cameraFormatChanged()                                   # 格式发生改变时发射信号

focusModeChanged()                                      # 焦点模式发生改变时发射信号
focusDistanceChanged(d:float)                           # 焦距发生改变时发射信号
focusPointChanged()                                     # 聚焦点发生改变时发射信号
customFocusPointChanged()                               # 自定义聚焦点发生改变时发射信号

exposureModeChanged()                                   # 曝光模式发生改变时发射信号
exposureCompensationChanged(value:float)                # 曝光补偿发生改变时发射信号
exposureTimeChanged(speed:float)                        # 曝光时间发生改变时发射信号
manualExposureTimeChanged(speed:float)                  # 自动曝光时间发生改变时发射信号

flashModeChanged()                                      # 快闪模式发生改变时发射信号
flashReady(ready:bool)                                  # 可以快闪时发射信号


isoSensitivityChanged(value:int)                        # 光敏感值发生改变时发射信号
manualIsoSensitivityChanged(value:int)                  # 自定义光敏感值发生改变时发射信号

minimumZoomFactorChanged(value:float)                   # 最小缩放系数发生改变时发射信号
maximumZoomFactorChanged(value:float)                   # 最大缩放系数发生改变时发射信号
zoomFactorChanged(value:int)                            # 缩放系数发生改变时发射信号

saturationChanged() 
supportedFeaturesChanged()                              # 支持的功能发生改变时发射信号
torchModeChanged()                                      # 辅助光源模式发生改变时发射信号
whiteBalanceModeChanged()                               # 白平衡模式发生改变时发射信号
colorTemperatureChanged()                               # 色温发生改变时发射信号

errorChanged()                                          # 错误状态发生改变时发射信号
errorOccurred(error:QCamera.Error, errorString:str)     # 出现错误时发射信号

三、媒体捕获器

  媒体捕获器 QMediaCaptureSession 是音频数据和视频数据的集散地,它接收从 QAudioInput 和 QCamera 传递过来的音频和视频,然后将音频转发给 QAudioOutput 播放音频,将视频转发给 QVideoWidegt 或 QGraphicsVideoItem 播放视频,或者将音频和视频转发给 QMdiaRecorder 录制音频和视频,转发给 QImageCapture 实现拍照功能。

  用 QMediaCaptureSession 创建实例对象的方法如下所示。

QMediaCaptureSession(parent:QObject=None)

  QMediaCaptureSession 类的常用方法如下:

setAudioInput(input:QAudioInput) -> None                # 设置音频输入
audioInput() -> QAudioInput                             # 获取音频输入
setAudioOutput(output:QAudioOutput) -> None             # 设置音频输出
audioOutput() -> QAudioOutput                           # 获取音频输出

setCamera(camera:QCamera) -> None                       # 设置视频接口
camera() -> QCamera                                     # 获取视频接口

setVideoOutput(output:QObject) -> None                  # 设置视频输出
videoOutput() -> QObject                                # 获取视频输出
setVideoSink(sink:QVideoSink) -> None                   # 设置视频接收器
videoSink() -> QVideoSink                               # 获取视频接收器

setImageCapture(imageCapture:QImageCapture) -> None     # 设置图像捕获器
imageCapture() -> QImageCapture                         # 获取图像捕获器

setRecorder(recorder:QMidiaRecorder) -> None            # 设置媒体记录器
recorder() -> QMeidaRecorder                            # 获取媒体记录器

  QMediaCaptureSession 类的常用信号如下:

audioInputChanged()             # 当音频输入发生改变时发射信号
audioOutputChanged()            # 当视频输出发生改变时发射信号
cameraChanged()                 # 当视频输入发生改变时发射信号
videoOutputChanged()            # 当视频输出发生改变时发射信号

imageCaptureChanged()           # 当图像捕获器发生改变时发射信号
screenCaptureChanged()          # 当屏幕捕获器发生改变时发射信号
windowCaptureChanged()          # 当窗口捕获器发生改变时发射信号

recorderChanged()               # 当记录器发生改变时发射信号
import sys

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout
from PySide6.QtMultimedia import QMediaDevices, QCamera, QMediaCaptureSession
from PySide6.QtMultimediaWidgets import QVideoWidget

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        self.setup_ui()

    def setup_ui(self):
        # 1、设置窗口对象大小
        self.resize(700, 500)
        layout_v = QVBoxLayout()
        self.setLayout(layout_v)

        # 2、显示视频的控件
        self.videoWidget = QVideoWidget()
        layout_v.addWidget(self.videoWidget)

        # 3、打开和停止摄像头的按钮
        self.button_open = QPushButton("打开摄像头")
        self.button_stop = QPushButton("关闭摄像头")
        layout_h = QHBoxLayout()
        layout_h.addWidget(self.button_open)
        layout_h.addWidget(self.button_stop)
        layout_v.addLayout(layout_h)

        # 3、媒体设备
        self.mediaDevice = QMediaDevices(self)

        # 4、获取默认的视频输入设备
        self.cameraDevice = self.mediaDevice.defaultVideoInput()
        # 5、根据视频输入设备定义视频接口
        self.camera = QCamera(self.cameraDevice)

        # 6、媒体捕获器
        self.mediaCaptureSession = QMediaCaptureSession(self)
        # 7、设备媒体捕获器的视频接口
        self.mediaCaptureSession.setCamera(self.camera)
        # 8、设置媒体捕获器的视频输出控件
        self.mediaCaptureSession.setVideoOutput(self.videoWidget)

        # 9、定义信号与槽的连接
        self.button_open.clicked.connect(self.camera.start)
        self.button_stop.clicked.connect(self.camera.stop)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

四、媒体格式

  在进行音频和视频的录制时,需要指定音频和视频的记录格式,以及媒体文件的存储格式,这些格式通过 QMediaFormat 类来定义。

  用 QMediaFormat 类创建媒体格式实例的方法如下所示。

QMediaFormat(format:QMediaFormat.FileFormat=QQMediaFormant.UnspecifiedFormat)
QMediaFormat(other:Union[QMediaFotmat, QMediaFotmant.FileFormat])

  QMediaFormat 类的常用方法如下:

# 实例方法
setFileFormat(f:QMediaFormat.FileFormat) -> None                                        # 设置文件格式
fileFormat() -> QMediaFormat.FileFormat                                                 # 获取文件格式
setAudioCodec(codec:QMediaFormat.AudioCode) -> None                                     # 设置音频编码格式
audioCodec() -> QMediaFormat.AudioCodec                                                 # 获取音频编码格式
setVideoCodec(codec:QMediaFormat.VideoCodec) -> None                                    # 设置视频编码格式
videoCodec() -> QMediaFormat.VideoCodec                                                 # 获取视频编码格式

supportedFileFormats(m:QMediaFormat.ConversionMode) -> List[QMediaFormat.FileFormat]    # 获取支持的文件编码格式列表
supportedAudioCodecs(m:QMediaFormat.ConversionMode) -> List[QMediaFormat.AudioCode]     # 获取支持的音频编码格式列表
supportedVideoCodecs(m:QMediaFormat.ConversionMode) -> List[QMediaFormat.VideoCode]     # 获取支持的视频编码格式列表
isSupported(mode:QMediaFormat.ConversionMode) -> bool                                   # 获取是否可以对某种编码格式编码或解码


# 静态方法
fileFormatName(fileFormat:QMediaFormat.FileFormat) -> str                               # 获取文件格式名称
fileFormatDescription(fileFormat:QMediaFormat.FileFormat) -> str                        # 获取文件格式信息
audioCodecName(codec:QMediaFormat.AudioCode) -> str                                     # 获取音频格式名称
audioCodecDescription(codec:QMediaFormat.AudioCode) -> str                              # 获取音频格式信息
videoCodecName(codec:QMediaFormat.VideoCode) -> str                                     # 获取视频格式名称
videoCodecDescription(codec:QMediaFormat.VideoCode) -> str                              # 获取视频格式信息

  分别用 supportedFileFormats(QMediaFormat.ConversionMode) 方法、supportedAudioCodecs(QMediaFormat.ConversionMode) 方法和 supportedVideoCodecs(QMediaFormat.ConversionMode) 方法获取编码或解码时支持的文件格式列表、音频编码格式列表和视频编码格式列表,参数 QMediaFormat.ConversionMode 可取值如下:

QMediaFormat.ConversionMode.Encode
QMediaFormat.ConversionMode.Decode

五、图像捕获

  用媒体捕获器 QMediaCaptureSession 的 setImageCapture(imageCapture:QImageCapture) 方法将 QImageCapture 与 QMediaCatureSession 关联,可以捕获图像,实现拍照功能。

  用 QImageCapture 类定义图像捕获的方法如下所示。

QImageCapture(parent:QObject=None)

  QImageCapture 类常用方法如下:

# 实例方法
isReadyForCapture() -> bool                                 # 获取是否可以拍照
captureSession() -> QMediaCaptureSession                    # 获取关联的捕捉器

setFileFormat(format:QImageCapture.FileFormat) -> None      # 设置文件格式
fileFormat() -> QImageCapture.FileFormat                    # 获取文件格式

setQuality(quality:QImageCapture.Quality) -> None           # 设置图像质量
quality() -> QImageCapture.Quality                          # 获取图像质量

setResolution(size:QSize) -> None                           # 设置分辨率
setResolution(width:int, height:int) -> None                # 设置分辨率
resolution() -> QSize                                       # 获取分辨率

setMetaData(metaData:QMediaMetaData) -> None                # 设置元数据
metaData() -> QMediaMetaData                                # 获取元数据
addMetaData(metaData:QMediaMetaData) -> None                # 添加元数据

error() -> QImageCapture.Error                              # 获取出错信息
errorString() -> str                                        # 获取出错信息
  
# 槽函数  
capture() -> int                                            # 进行拍照
captureToFile(location="") -> int                           # 拍照到文件

# 静态方法
fileFormatDescription(c:QImageCapture.FileFormat) -> str    # 获取格式的信息
fileFormatName(c:QImageCapture.FileFormat) -> str           # 获取格式的名称
supportedFormats() -> List[QImageCapture.FileFormat]        # 获取支持的格式

  当 isReadyForCapture() 的返回值是 True 时,可以进行拍照;用 capture() 方法进行拍照,返回值是拍照的识别号 ID,同时会发送 imageCaptured(id:int,preview:QImage) 信号和 imageExposed(id:int) 信号,可以获取拍摄的图像;也可以用 captureToFile(location:str='') 方法直接将拍摄的图像保存到文件中,同时发送 imageCaptured(id:int,preview:QImage) 信号、imageExposed(id:int) 信号和 imageSaved(id:int,fileName:str) 信号,如果没有给出保存的文件名和路径,则使用默认的路径和文件名,如果只给出文件名,则保存到默认路径下,完整路径可以通过 imageSaved(id:int,fileName:str) 信号的参数获取。

  用 error() 方法获取拍照时的出错状态,返回值是 QImageCapture.Error 枚举值,可取值如下:

QImageCapture.NoError                       # 没有错误
QImageCapture.NotReadyError                 # 设备没准备好
QImageCapture.ResourceError                 # 设备没准备好或不可用
QImageCapture.OutOfSpaceError               # 存储空间不够
QImageCapture.NotSupportedFeatureError      # 设备不支持拍照
QImageCapture.FormatError                   # 格式出错

  用 setFileFormat(format:QImageCapture.FileFormat) 方法设置拍照的格式,参数是 QImageCapture.FileFormat 的枚举值,可取值如下:

QImageCapture.FileFormat.JPEG
QImageCapture.FileFormat.PNG
QImageCapture.FileFormat.Tiff
QImageCapture.FileFormat.WebP
QImageCapture.FileFormat.UnspecifiedFormat
QImageCapture.FileFormat.LastFileFormat

  用 setQuality(quality:QImageCapture.Quality) 方法设置图像质量,参数是 QImageCapture.Quality 的枚举值,可取值如下:

QImageCapture.Quality.VeryLowQuality
QImageCapture.Quality.LowQuality
QImageCapture.Quality.NormalQuality
QImageCapture.Quality.HighQuality
QImageCapture.Quality.VeryHighQuality

  QImageCapture 类常用信号如下:

readyForCaptureChanged(ready:bool)                                  # 准备状态发生改变时发射信号
imageCaptured(id:int, preview:QImage)                               # 捕捉到图象时发射信号
imageExposed(id:int)                                                # 图像曝光时发射信号
imageSaved(id:int, fileName:str)                                    # 保存图像时发射信号
imageAvailable(id:int, frame:QVideoFrame)                           # 可以获取图像时发射信号
metaDataChanged()                                                   # 元数据发生改变时发射信号
qualityChanged()                                                    # 图像质量发生改变时发射信号
errorOccurred(id:int, error:QImageCapture.Error, errorString:str)   # 出现错误时发射信号
errorChanged()                                                      # 错误状态发生改变时发射信号
fileFormatChanged()                                                 # 文件格式发生改变时发射信号

  其中 imageAvailable(id:int,frame:QVideoFrame) 信号的参数 QVideoFrame 是视频帧,利用 QVideoFrame 的 toImage() 方法可以得到 QImage。

import sys
import os, time

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout
from PySide6.QtMultimedia import QMediaDevices, QCamera
from PySide6.QtMultimedia import QMediaCaptureSession, QImageCapture
from PySide6.QtMultimediaWidgets import QVideoWidget


class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        self.imageCapture = None
        self.setup_ui()

    def setup_ui(self):
        # 1、设置窗口对象大小
        self.resize(700, 500)
        layout_v = QVBoxLayout()
        self.setLayout(layout_v)

        # 2、显示视频的控件
        self.videoWidget = QVideoWidget()
        layout_v.addWidget(self.videoWidget)

        # 3、打开和停止摄像头的按钮
        self.button_camera_action = QPushButton("打开摄像头")
        self.button_camera_take_photo = QPushButton("拍照")

        layout_h = QHBoxLayout()
        layout_h.addWidget(self.button_camera_action)
        layout_h.addWidget(self.button_camera_take_photo)
        layout_v.addLayout(layout_h)

        # 3、媒体设备
        self.mediaDevice = QMediaDevices(self)

        # 4、获取默认的视频输入设备
        self.cameraDevice = self.mediaDevice.defaultVideoInput()
        # 5、根据视频输入设备定义视频接口
        self.camera = QCamera(self.cameraDevice)

        # 6、媒体捕获器
        self.mediaCaptureSession = QMediaCaptureSession(self)
        # 7、设备媒体捕获器的视频接口
        self.mediaCaptureSession.setCamera(self.camera)
        # 8、设置媒体捕获器的视频输出控件
        self.mediaCaptureSession.setVideoOutput(self.videoWidget)

        # 9、定义信号与槽的连接
        self.button_camera_action.clicked.connect(self.camera_action)
        self.button_camera_take_photo.clicked.connect(self.take_photo)

    def camera_action(self):
        if self.button_camera_action.text() == "打开摄像头":
            # 打开摄像头
            self.camera.start()
            # 摄像头操作按钮文本显示为关闭摄像头
            self.button_camera_action.setText("关闭摄像头")

            # 创建图片捕获对象,并关联摄像头
            self.imageCapture = QImageCapture()
            # 设置图像图示
            self.imageCapture.setFileFormat(QImageCapture.FileFormat.JPEG)
            # 设置分辨率
            self.imageCapture.setResolution(1920, 1080)
            # 设置图片质量
            self.imageCapture.setQuality(QImageCapture.Quality.HighQuality)

            # 设置捕获器
            self.mediaCaptureSession.setImageCapture(self.imageCapture)
        elif self.button_camera_action.text() == "关闭摄像头":
            # 关闭摄像头
            self.camera.stop()
            # 摄像头操作按钮文本显示为打开摄像头
            self.button_camera_action.setText("打开摄像头")

            self.imageCapture = None

    def take_photo(self):
        if self.imageCapture:
            fileName = f"{os.getcwd()}/{time.strftime('%Y%m%d%H%M%S', time.localtime())}.jpeg"
            self.imageCapture.captureToFile(fileName)

if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

六、媒体录制

  QMediaRecorder 可以录制从 QMediaCaptureSession 获取的音频和视频,并对音频和视频进行编码,需要用 QMediaCaptureSession的setRecorder(recorder:QMediaRecorder) 方法设置关联的捕获器。

  用 QMediaRecorder 创建实例的方法如下所示。

QMediaRecorder(parent:QObject=None)

  QMediaRecorder 类的常用方法如下:

# 实例方法
isAvailable() -> bool                                                           # 获取是否可以录制

duration() -> int                                                               # 获取录制时间
recorderState() -> QMediaRecorder.recorderState                                 # 获取录制状态

error() -> QMediaRecorder.Error                                                 # 获取出错内容
errorString() -> str                                                            # 获取错误信息

setAudioBitRate(bitRate:int) -> None                                            # 设置音频比特率
audioBitRate() -> int                                                           # 获取音频比特率
setAudioChannelCount(channels:int) -> None                                      # 设置音频通道数
audioChannelCount() -> int                                                      # 获取音频通道数
setAudioSampleRate(sampleRate:int) -> None                                      # 设置音频采样率
audioSampleRate() -> int                                                        # 获取音频采样率

setEncodingMode(mode:QMediaRecorder.EncodingMode) -> None                       # 设置编码格式
encodingMode() -> QMeidaRecorder.encodingMode                                   # 获取编码格式
setMediaFormat(format:Union[QMediaFormat, QMediaFormat.FileFotmat]) -> None     # 设置媒体格式

setQuality(quality:QMediaRecorder.Quality) -> None                              # 设置录制质量
quality() -> QMediaRecorder.Quality                                             # 获取录制质量
setVideoBitRate(bitRate:int) -> None                                            # 设置视频比特率  
videoBitRate() -> int                                                           # 获取视频比特率
setVideoFrameRate(frameRate:float) -> None                                      # 设置视频帧速
videoFrameRate() -> float                                                       # 获取视频帧速

setVideoResolution(size:QSize) -> None                                          # 设置视频分辨率
setVideoResolution(width:int, height:int) -> None                               # 设置视频分辨率
videoResolution() -> QSize                                                      # 获取视频分辨率

setMetaData(metaData:QMediaMetaData) -> None                                    # 设置媒体元数据
metaData() -> QMediaMeta                                                        # 获取媒体元数据
addMetaData(metaData:QMediaMetaData) -> None                                    # 添加媒体元数据

setOutputLocation(location:QUrl) -> None                                        # 设置媒体输出位置
outputLocation() -> QUrl                                                        # 获取输出位置
actualLocation() -> QUrl                                                        # 获取实际的输出位置   

# 槽方法
record() -> None                                                                # 开始录制
pause() -> None                                                                 # 暂停录制
stop() -> None                                                                  # 停止录制

  用 recorderState() 方法获取录制状态,返回值是 QMediaRecorder.RecorderState 的枚举值,可取值如下:

QMediaRecorder.RecorderState.StoppedState
QMediaRecorder.RecorderState.RecordingState
QMediaRecorder.RecorderState.PausedState

  录制过程中如果出错,可以用 error() 方法获取出错内容,返回值是 QMediaRecorder.Error 的枚举值,可取值如下:

QMediaRecorder.Error.NoError                 # 没有问题
QMediaRecorder.Error.ResourceError           # 设备没有准备好
QMediaRecorder.Error.FormatError             # 不支持该格式
QMediaRecorder.Error.OutOfSpaceError         # 存储空间不足
QMediaRecorder.Error.LocationNotWritable     # 输出位置不可写

  用 setEncodingMode(QMediaRecorder.EncodingMode) 方法设置编码模式,参数是 QMediaRecorder.EncodingMode 的枚举值,可取值如下:

QMediaRecorder.EncodingMode.ConstantQualityEncoding      # 常质量编码
QMediaRecorder.EncodingMode.ConstantBitRateEncoding      # 常比特率编码
QMediaRecorder.EncodingMode.AverageBitRateEncoding       # 平均比特率编码
QMediaRecorder.EncodingMode.TwoPassEncoding              # 二次编码

  用 setQuality(quality:QMediaRecorder.Quality) 方法设置录制质量,参数是 QMediaRecorder.Quality 的枚举值,可取如下:

QMediaRecorder.Quality.VeryLowQuality
QMediaRecorder.Quality.LowQuality
QMediaRecorder.Quality.NormalQuality
QMediaRecorder.Quality.HighQuality
QMediaRecorder.Quality.VeryHighQuality

  QMediaRecorder 类的常用信号如下:

actualLocationChanged(location:QUrl)                            # 存储位置发生改变时发射信号
durationChanged(duration:int)                                   # 录制时间发生改变时发射信号
errorChanged()                                                  # 错误状态发生改变时发射信号
errorOccurred(error:QMediaRecorder.Error, errorString:str)      # 出现错误时发射信号
mediaFormatChanged()                                            # 格式发生改变时发射信号
metaDataChanged()                                               # 元数据发生改变时发射信号
recorderStateChanged(state:QMediaRecorder.RecorderState)        # 录制状态发生改变时发射信号
import sys
import os, time

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout
from PySide6.QtMultimedia import QMediaDevices, QCamera
from PySide6.QtMultimedia import QMediaCaptureSession, QAudioInput
from PySide6.QtMultimedia import QMediaRecorder, QMediaFormat
from PySide6.QtMultimediaWidgets import QVideoWidget
from PySide6.QtCore import QUrl

class MyWidget(QWidget):
    def __init__(self):
        # 1、调用父类的__init__()方法
        super().__init__()
        self.mediaRecorder = None
        self.setup_ui()

    def setup_ui(self):
        # 1、设置窗口对象大小
        self.resize(700, 500)
        layout_v = QVBoxLayout()
        self.setLayout(layout_v)

        # 2、显示视频的控件
        self.videoWidget = QVideoWidget()
        layout_v.addWidget(self.videoWidget)

        # 3、打开和停止摄像头的按钮
        self.button_camera_action = QPushButton("打开摄像头")
        self.button_camera_recorder_action = QPushButton("开始录像")
        self.button_camera_recorder_stop = QPushButton("停止录像")

        layout_h = QHBoxLayout()
        layout_h.addWidget(self.button_camera_action)
        layout_h.addWidget(self.button_camera_recorder_action)
        layout_h.addWidget(self.button_camera_recorder_stop)
        layout_v.addLayout(layout_h)

        # 3、媒体设备
        self.mediaDevice = QMediaDevices(self)

        # 4、获取默认的视频输入设备
        self.cameraDevice = self.mediaDevice.defaultVideoInput()
        # 5、根据视频输入设备定义视频接口
        self.camera = QCamera(self.cameraDevice)

        # 6、媒体捕获器
        self.mediaCaptureSession = QMediaCaptureSession(self)
        # 7、设备媒体捕获器的视频接口
        self.mediaCaptureSession.setCamera(self.camera)
        # 8、设置媒体捕获器的视频输出控件
        self.mediaCaptureSession.setVideoOutput(self.videoWidget)

        # 9、定义信号与槽的连接
        self.button_camera_action.clicked.connect(self.camera_action)
        self.button_camera_recorder_action.clicked.connect(self.camera_recorder_action)
        self.button_camera_recorder_stop.clicked.connect(self.camera_recorder_stop)

    def camera_action(self):
        if self.button_camera_action.text() == "打开摄像头":
            # 打开摄像头
            self.camera.start()
            # 摄像头操作按钮文本显示为关闭摄像头
            self.button_camera_action.setText("关闭摄像头")

            # 创建媒体录制对象,并关联摄像头
            self.mediaRecorder = QMediaRecorder(self.camera)
    
            # 设置输出视频的格式
            self.mediaRecorder.setMediaFormat(QMediaFormat.FileFormat.AVI)
            # 设置分辨率
            self.mediaRecorder.setVideoResolution(1920, 1080)
            # 设置输出视频的质量
            self.mediaRecorder.setQuality(QMediaRecorder.Quality.HighQuality)
    
            # 设置媒体输出位置
            fileName = f"{os.getcwd()}/{time.strftime('%Y%m%d%H%M%S', time.localtime())}.avi"
            self.mediaRecorder.setOutputLocation(QUrl.fromLocalFile(fileName))
    
            # 设置音频输出
            self.audioInput = QAudioInput()
            self.mediaCaptureSession.setAudioInput(self.audioInput)

            # 设置捕获器
            self.mediaCaptureSession.setRecorder(self.mediaRecorder)

            self.mediaRecorder.errorOccurred.connect(self.error)
        elif self.button_camera_action.text() == "关闭摄像头":
            # 关闭摄像头
            self.camera.stop()
            # 摄像头操作按钮文本显示为打开摄像头
            self.button_camera_action.setText("打开摄像头")

            # 结束录制
            if self.mediaRecorder:
                self.mediaRecorder.stop()
                self.button_camera_recorder_action.setText("开始录像")

                self.mediaRecorder = None

    def camera_recorder_action(self):
        if self.mediaRecorder:
            if self.button_camera_recorder_action.text() == "开始录像":
                # 开始录像
                self.mediaRecorder.record()
                # 录制操作按钮文本显示为暂停录像
                self.button_camera_recorder_action.setText("暂停录像")
            elif self.button_camera_recorder_action.text() == "暂停录像":
                # 暂停录像
                self.mediaRecorder.pause()
                # 录制操作按钮文本显示为开始录像
                self.button_camera_recorder_action.setText("开始录像")

    def camera_recorder_stop(self):
        if self.mediaRecorder:
            # 结束录像
            self.mediaRecorder.stop()
            # 录制操作按钮文本显示为开始录像
            self.button_camera_recorder_action.setText("开始录像")

            # 关闭摄像头
            self.camera.stop()
            # 摄像头操作按钮文本显示为打开摄像头
            self.button_camera_action.setText("打开摄像头")

            self.mediaRecorder = None

    def error(self, error, errorString):
        print(error)
        print(errorString)


if __name__ == "__main__":
    # 1、创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2、创建一个窗口
    window = MyWidget()
    # 3、展示窗口
    window.show()
    # 4、进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())

标签:视频,None,QCamera,媒体,self,录制,34,获取,camera
From: https://www.cnblogs.com/FlurryHeart/p/18686609

相关文章

  • 34. 在排序数组中查找元素的第一个和最后一个位置
    给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1,-1]。你必须设计并实现时间复杂度为 O(logn) 的算法解决此问题。 示例1:输入:nums=[5,7,7,8,8,10],tar......
  • 打卡信奥刷题(647)用C++信奥P8342[普及组/提高] [COCI2021-2022#6] Med
    [COCI2021-2022#6]Med题目描述今天是公开赛的最后一轮。人们知道这两个比赛采用相同的计分系统。更准确地说,两场比赛都有666轮,每轮的积分在......
  • 【Azure APIM】APIM服务配置网络之后出现3443端口不通,Management Endpoint不健康状态
    问题描述APIM服务在配置网络之后,查看网络状态发现ManagementEndpoint是不健康状态,提示无法连接到3443端口。错误消息:Failedtoconnecttomanagementendpointatxxxxxxxx.management.azure-api.cn:3443foraservicedeployedinavirtualnetwork.Makesuretofollo......
  • P2234 [HNOI2002] 营业额统计
    P2234[HNOI2002]营业额统计题目翻译:给定\(n\)个数,每一个数都要统计其最小波动值,波动值的定义是当天银收额和之前某次的营收额的差的绝对值,而要求每一天最小波动值的和(第一天波动值为当天营收额)思路:分析题目可以发现,最小波动值就是当天营收额与之前小于它的最大营收额的差......
  • 33. 媒体操作
    一、音频播放  QSoundEffect可以用来播放无压缩的音频文件(典型的是.wav文件),通过它我们不仅能够以低延迟的方式来播放音频,还能够对音频进行更进一步的操作(比如控制音量)。该类非常适合用来播放交互音效,如弹出框的提示音、游戏音效等。  我们可以在终端中使用pip安装pysi......
  • [超表面论文快讯-34] Light: Science & Applications-电磁超材料强化学习智能体-北京
    栏目介绍:“论文快讯”栏目旨在精简地分享一周内发表在高水平期刊上的Metasurface领域研究成果,帮助读者及时了解领域前沿动态,如果对专栏的写法或内容有什么建议欢迎留言,后续会陆续开启其他专栏,敬请期待。论文基本信息标题:Electromagneticmetamaterialagent作者:......
  • 【题解】Luogu P4340 [SHOI2016] 随机序列
    简单手摸后发现,答案就是这么一个式子:\[(3^{n-1}-3^{n-2})a_1+(3^{n-2}-3^{n-3})a_1a_2+\dots+(3^1-3^0)a_1a_2\dotsa_{n-1}+a_1a_2\dotsa_n\]啊当然证明也是好证的,对于\(a_1\)这一项,它后面放+或-都会对系数加一,而放*不会影响系数,因此系数就是总数的三分之二。其它前缀......
  • P3456 [POI2007] GRZ-Ridges and Valleys
    P3456[POI2007]GRZ-RidgesandValleys背景本人蒟蒻,只会写DFS。本题BFS更好思路这是一道很明显的搜索题,题目要求我们找到山峰和山谷山峰?不就是在这个高度周围没有比它跟高的地方山谷?不就是在这个高度周围没有比它更矮的地方因此我们只需要用\(DFS\)遍历遇到的所......
  • 还在手动录直播?学会这招,在群晖 / 飞牛 Nas 等服务器一键部署 40 + 国内外热门直播自动
    文章目录......
  • leetcode349-两个数组的交集
    leetcode349实现利用哈希set进行去重,然后循环nums2,如果nums2中的元素是在去重后的num1中出现过的,就存放在set2中,因为最后要返回的是不重复的数组,所以先放在set2,让其进行去重,最后把set2转为数组方法1varintersection=function(nums1,nums2){constset1=[........