51959


pyqt5でwmvの動画ファイルを再生する際、再生速度を変化させたいです。次は試しに書いたコードです。

[code]

    from PyQt5.QtCore import QDir, Qt, QUrl
    from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
    from PyQt5.QtMultimediaWidgets import QVideoWidget
    from PyQt5.QtWidgets import (QApplication, QFileDialog, QHBoxLayout, QLabel,
            QPushButton, QSizePolicy, QSlider, QStyle, QVBoxLayout, QWidget, QComboBox)
    
    
    class VideoPlayer(QWidget):
    
        def __init__(self, parent=None):
            super(VideoPlayer, self).__init__(parent)
    
            self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
    
            videoWidget = QVideoWidget()
    
            openButton = QPushButton("Open...")
            openButton.clicked.connect(self.openFile)
    
            self.playButton = QPushButton()
            self.playButton.setEnabled(False)
            self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            self.playButton.clicked.connect(self.play)
    
            self.rateBox = QComboBox(self)
            self.rateBox.addItem("0.5x", 0.5)
            self.rateBox.addItem("1.0x", 1.0)
            self.rateBox.addItem("2.0x", 2.0)
            self.rateBox.setCurrentIndex(1)
            self.rateBox.activated[str].connect(self.changerate)
    
            self.positionSlider = QSlider(Qt.Horizontal)
            self.positionSlider.setRange(0, 0)
            self.positionSlider.sliderMoved.connect(self.setPosition)
    
            self.errorLabel = QLabel()
            self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                    QSizePolicy.Maximum)
    
            controlLayout = QHBoxLayout()
            controlLayout.setContentsMargins(0, 0, 0, 0)
            controlLayout.addWidget(openButton)
            controlLayout.addWidget(self.playButton)
            controlLayout.addWidget(self.rateBox)
            controlLayout.addWidget(self.positionSlider)
    
            layout = QVBoxLayout()
            layout.addWidget(videoWidget)
            layout.addLayout(controlLayout)
            layout.addWidget(self.errorLabel)
    
            self.setLayout(layout)
    
            self.mediaPlayer.setVideoOutput(videoWidget)
            self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
            self.mediaPlayer.positionChanged.connect(self.positionChanged)
            self.mediaPlayer.durationChanged.connect(self.durationChanged)
            self.mediaPlayer.error.connect(self.handleError)
    
        def openFile(self):
            fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                    QDir.homePath())
    
            if fileName != '':
                self.mediaPlayer.setMedia(
                        QMediaContent(QUrl.fromLocalFile(fileName)))
                self.playButton.setEnabled(True)
    
        def play(self):
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                self.mediaPlayer.pause()
            else:
                self.mediaPlayer.play()
    
        def mediaStateChanged(self, state):
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPause))
            else:
                self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPlay))
    
        def positionChanged(self, position):
            self.positionSlider.setValue(position)
    
        def durationChanged(self, duration):
            self.positionSlider.setRange(0, duration)
    
        def setPosition(self, position):
            self.mediaPlayer.setPosition(position)
    
        def handleError(self):
            self.playButton.setEnabled(False)
            self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
    
        def changerate(self):
            rate=self.rateBox.itemData(self.rateBox.currentIndex())
            self.mediaPlayer.setPlaybackRate(rate)
    
    
    if __name__ == '__main__':
    
        import sys
    
        app = QApplication(sys.argv)
    
        player = VideoPlayer()
        player.resize(320, 240)
        player.show()
    
        sys.exit(app.exec_())
    
[/code]

これを実行すると次のようなGUIが作成されます。  
[![画像](https://i.stack.imgur.com/uFseV.png)](https://i.stack.imgur.com/uFseV.png)  
ここで、動画を開き、再生したときにコンボボックスで再生速度を変化させたいのですが。上のコードでは変化が見られませんでした。終始1倍速で再生が続いただけでした。どのように修正すればよいのでしょうか。


CC BY-SA 4.0
2019-01-14T01:50:22.227
51958
2019-01-14T23:57:01.293
26529
question
python3 pyqt5
pyqt5でwmv動画を再生させる時に、再生速度を変化させたい


パラメータの型が PySide2.QtCore.qreal のようなので、  
設定する前に明示的に型宣言・変換してみてはどうでしょうか？

>
> [PySide2.QtMultimedia.QMediaPlayer.setPlaybackRate(rate)](https://doc.qt.io/qtforpython/PySide2/QtMultimedia/QMediaPlayer.html#PySide2.QtMultimedia.PySide2.QtMultimedia.QMediaPlayer.setPlaybackRate)  
>  Parameters: rate – PySide2.QtCore.qreal

[How to use QVariant/ja](https://wiki.qt.io/How_to_use_QVariant/ja)

一応、すべての再生サービスがサポートしているわけではない、という注意書きがありますが。  
[playbackRate ：
qreal](https://code.i-harness.com/ja/docs/qt%7E5.11/qmediaplayer#playbackRate-
prop)

> このプロパティは、現在のメディアの再生レートを保持します。
>
> この値は、メディアの標準再生レートに適用される乗数です。 デフォルトでは、この値は1.0で、メディアが標準ペースで再生されていることを示します。
> 値が1.0より大きい場合は再生レートが高くなります。 0より小さい値を設定することができ、標準ペースの乗数でメディアが巻き戻されることを示します。
>
> **すべての再生サービスが再生レートの変更をサポートしているわけではありません。**
> 早送りまたは巻き戻しの間、オーディオおよびビデオの状態および品質に関して定義されたフレームワークである。

注)強調は引用者による。

ちなみに `rate` 変数が `self.rate` で無いのは一時的な変数だからですかね？

* * *

C++で作った場合は、少し古い版数のQtでも動作しているようです。

[Qt(キュート)プログラム実行まで［サンプル(後編)］](http://dorafop.my.coocan.jp/Qt/Qt006.html)

> コンボで再生速度を選択した時の処理  
>  再生速度を選択されたレートに変更しますが、環境に依存するので機能しないことがあります。
[code]

    void MainWindow::activeRateCombo(int comboIx) {
        QComboBox *combo = static_cast<QComboBox *>(sender());
        qreal rate = combo->itemData(comboIx).toDouble();
        if (rate != player->playbackRate()) {
            player->setPlaybackRate(rate);
        }
    }
    
[/code]

> ※0.5x:0.5倍速、1.0x:通常速度、2.0x:2倍速

* * *

**追記**  
ちょっと調べたら、3カ月前に同様の質問があったけれど、回答が付いていません。  
[python pyqt5 setPlaybackRate shows a black screen when changing video playing
rate](https://stackoverflow.com/q/52736113/9014308)

こちらは巻き戻し再生が出来ないという質問ですが、解決していないようです。  
[QMediaPlayer negative playbackRate doesn't rewind
video](https://stackoverflow.com/q/52155722/9014308)

ただし、下側の回答の方にキー押下(A,Z,Y)で `setPlaybackRate`
を呼び出すコーディング例が付いているので、これをそのまま動かして試してみるのはどうでしょう？

* * *

**さらに追記**  
試しに動かしてみたら、Audio系が速度変更をサポートしていないと出ました。

> DirectShowPlayerService::doSetRate: Audio device or filter does not support
> rate: 0.50. Falling back to previous value.

ご質問のものも、紹介した本家S.O.サイトのものも、かつそれらのどの倍率でもエラーになりました。細かく確認すれば、どこかの倍率はサポートしているのかもしれませんが、望み薄ですね。

* * *

**見直し**  
上記を受けてソースを見ると、どちらのプログラムも `AudioRole` を設定していないですね。  
何か適切な(あるいは単にデフォルト的な) `AudioRole` を設定することで動作する可能性が考えられます。


CC BY-SA 4.0
2019-01-14T02:51:43.723
51959
2019-01-14T23:57:01.293
2020-06-17T08:14:45.997
-1
26370
51958
answer