IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Python Discussion :

[PyQt5 - QtMultimedia] Un lecteur basique pour écouter une radio internet


Sujet :

Contribuez Python

  1. #1
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut [PyQt5 - QtMultimedia] Un lecteur basique pour écouter une radio internet
    Bonjour,

    Je me suis attaqué depuis quelques jours au développement d'un programme d'écoute de radios internet sur mon PC, et ça marche vraiment très bien! J'ai pensé que ça pouvait en intéresser certains, et je dédie même cette application à ceux qui pensent encore que Python n'est qu'un langage de script.. .

    Voilà une version basique. Vous voyez que la partie purement écoute prend... 3 lignes! Et en fait, il a fallu créer une petite fenêtre uniquement pour pouvoir arrêter le programme.

    L'écoute de la radio internet utilise le module QtMultimedia de PyQt5.

    A noter qu'il y a très peu de modifications à faire pour que le même programme lise un fichier audio mp3: il suffit de faire QUrl.fromLocalFile(url) au lieu de QUrl(url), ce qui ajoutera simplement "file:///" au début de l'adresse disque du fichier.

    Le programme est prévu pour être lancé avec l'url de la radio internet en argument de la ligne de commande. Avec un bureau graphique (Windows, Linux, MacOS), on peut créer une icône sur le bureau, qui lancera le programme avec la radio souhaité en argument.

    Voilà le code proposé, très largement documenté (testé avec Python v3.5 et PyQt5 v5.9):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Python3 v3.5 PyQt5 v5.9
     
    """
    Lecteur basique d'une radio internet
    Auteur: Jean-Paul Vidal dit "Tyrtamos" (mai 2018)
     
    Pour les adresses web des radios francophones, voir par exemple:
    http://fluxradios.blogspot.fr/
     
    Exemple pour la radio "Frequence 3":
    http://ice.stream.frequence3.net/frequence3-128.mp3
     
    Pour télécharger une icône, voir par exemple:
    https://icones8.fr/icon/2308/tour-de-radio
    """
     
    import sys
    import os
     
    from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, 
                                 QGridLayout, QMessageBox, QStyleFactory)
    #from PyQt5.QtGui import QIcon # à mettre s'il y a une icône pour la fenêtre
    from PyQt5.QtCore import Qt, QUrl
    from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
     
    #############################################################################
    class RadioWeb(QWidget):
     
        def __init__(self, qurlradio, parent=None):
            super().__init__(parent)
            self.setWindowTitle("Radio internet")
            self.resize(250,50)
            self.setAttribute(Qt.WA_DeleteOnClose, True)
     
            # ajoute un bouton pour arrêter le programme (et l'écoute)
            self.bouton = QPushButton("Arrêter", self)
            self.bouton.setStyleSheet("background-color:lightgreen;")
            self.bouton.clicked.connect(self.close) # fermeture
            layout = QGridLayout()
            layout.addWidget(self.bouton, 0, 0) # bouton au milieu de fenêtre
            self.setLayout(layout)
     
            # crée le player
            self.player = QMediaPlayer()
     
            # et lance l'écoute de la radio demandée
            self.player.setMedia(QMediaContent(qurlradio))
            self.player.play()
     
    #############################################################################
    if __name__ == "__main__":
     
        # active la bibliothèque graphique
        app = QApplication(sys.argv)
     
        # met un style pour toute l'application
        app.setStyle(QStyleFactory.create("Fusion"))
     
        # option: met une icone pour l'application
        #icone = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icons8-tour-de-radio-50.png")
        #app.setWindowIcon(QIcon(icone))
     
        # récupére l'argument en ligne de commande
        if len(sys.argv)>1:
            url = sys.argv[1]
            qurl = QUrl(url)
        else:
            QMessageBox.information(None, 
                "Chargement de la radio", 
                "Aucune radio n'a été demandée")
            app.quit()
            sys.exit()
     
        # lance la fenêtre pour l'écoute de la radio
        radioweb = RadioWeb(qurl)
        radioweb.show()
     
        # boucle de traitement des évènements et sortie du programme    
        sys.exit(app.exec_())
    Voilà la petite fenêtre qui s'affiche (avec l'option icône):

    Nom : radiointernet.jpg
Affichages : 1925
Taille : 20,1 Ko

    Il s'agit ici d'une version minimale pour l'écoute d'une seule radio. Mais on peut faire plus complet et plus confortable en ajoutant une "playlist", alimentée par une liste de radios prédéfinie, et un moyen pour sélectionner la radio à écouter. Pour cela, j'utilise un simple fichier texte "radioweb.txt" pour la liste des radios qui m'intéressent, et un QTableWidget pour sélectionner la radio à écouter dans cette liste avec un simple double-clic. En ajoutant une "pause" et un "reprendre" avec un menu popup, on peut s'adapter rapidement à un coup de téléphone... Voilà une copie d'écran:

    Nom : radioweb.jpg
Affichages : 2102
Taille : 48,7 Ko

    Pour être encore plus pratique, ce dernier lecteur est chez moi intégré dans un "QSystemTrayIcon" qui permet à ce programme de ne prendre que la place d'une icône dans la zone de notification. Ce programme est chargé automatiquement à l’allumage du PC, et je n'ai que 2 clic de souris à faire pour lancer l'écoute de la radio qui m'intéresse. En écrivant ce message, j'écoute la radio "Fréquence 3" (url = "http://ice.stream.frequence3.net/frequence3-128.mp3").

    Et, cerise sur le gâteau, on peut facilement créer un exécutable autonome avec pyinstaller. C'est ce que je fais sous Windows, et j'utilise même l'option "onefile" pour n'avoir qu'un seul fichier "radioweb.exe" qui contient tout, y compris l'interpréteur Python, et qui peut donc être exécuté sur un PC qui n'a pas Python installé.

    Je n'ai pas encore eu le temps de mettre ces extensions sur mon site web, mais ça va venir... Et ça irait plus vite si je savais que des personnes de ce forum étaient intéressées.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  2. #2
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut.

    Il faut installer quelque chose d'autre de particulier, car sur linux (debian) j'ai une erreur :

    defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.mediaplayer"
    Au cas où : version 5.10.1 sur python3.6
    Le temps ronge l'amour comme l'acide.

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Apparemment sous Linux (je n'ai pas encore essayé), il faut installer quelque chose en plus.

    Voir par exemple la discussion ici: https://forum.qt.io/topic/28620/solv...mediaplayer/30.

    Je vais essayer sur mon linux (linuxmint issu de ubuntu, lui-même issu de debian)
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    En réalité cela vient certainement de la bibliothèque pour la version 3.6 de python.

    Car j'avais pas testé (désolé), mais cela fonctionne bien avec python2, et python3.4(.8), en revanche avec python 3.6(.4) non, malgré que j'ai toutes les dépendances requises installées.
    Le temps ronge l'amour comme l'acide.

  5. #5
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Merci Tyrtamos.

    Pas de problème sous Ubuntu, Bistouille n'oublie pas que sous Debian et dérivées PyQt est morcelé en divers packages exemple: python3-pyqt5.qtmultimedia

    Au passage l'url de Classic-21 (Les gens du Nord connaissent) https://radios.rtbf.be/classic21-128.mp3

    Quand j'ai implémenté une visionneuse vidéo dans Qarte j'ai aussi été surpris de la simplicité du code.

    et puisque c'est dimanche, j'ai mis le code dans une petite interface pour ceux qui veulent un exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
     
    # -*- coding: utf-8 -*-
     
    import sys
     
    from PyQt5.QtCore import Qt, QUrl
    from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QSlider,
                                 QVBoxLayout, QHBoxLayout, QLineEdit, QLabel,
                                 QSpacerItem, QSizePolicy)
    from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
    from PyQt5.QtMultimediaWidgets import QGraphicsVideoItem, QVideoWidget
     
    class Main(QWidget):
        def __init__(self):
            super().__init__()
            self.layout = QVBoxLayout(self)
            self.layout.setContentsMargins(0, 0, 0, 0)
            self.player_wdg = QVideoWidget()
            self.layout.addWidget(self.player_wdg)
            self.layout1 = QHBoxLayout()
            self.url_led = QLineEdit(self)
            self.layout1.addWidget(self.url_led)
            self.play_btn = QPushButton("Play", self)
            self.layout1.addWidget(self.play_btn)
            self.pause_btn = QPushButton("Pause", self)
            self.layout1.addWidget(self.pause_btn)
            self.stop_btn = QPushButton("Stop", self)
            self.layout1.addWidget(self.stop_btn)
            spc1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
            self.layout1.addItem(spc1)
            self.level_sld = QSlider(self)
            self.level_sld.setOrientation(Qt.Horizontal)
            self.level_sld.setValue(50)
            self.layout1.addWidget(self.level_sld)
            self.level_lbl = QLabel(self)
            self.level_lbl.setAlignment(Qt.AlignRight|
                                        Qt.AlignTrailing|Qt.AlignVCenter)
            self.level_lbl.setText("50")
            self.layout1.addWidget(self.level_lbl)
            self.layout.addLayout(self.layout1)
            self.player = VideoPlayer(self)
            self.play_btn.clicked.connect(self.preview_current_video)
            self.pause_btn.clicked.connect(self.pause_preview)
            self.stop_btn.clicked.connect(self.stop_preview)
            self.level_sld.valueChanged.connect(self.set_sound_level)
            self.player_wdg.wheelEvent = self.on_video_wheel_event
            self.url_led.editingFinished.connect(self.url_changed)
            self.current_video = False
     
        def url_changed(self):
            url = self.url_led.text()
            if url.startswith("http"):
                url = QUrl(url)
            else:
                url = QUrl.fromLocalFile(url)
            self.current_video = url
     
        def preview_current_video(self):
            if self.player.is_on_pause:
                self.set_running_player()
                self.player.start()
                return
     
            if not self.current_video:
                return
     
            self.player.set_media(self.current_video)
            self.set_running_player()
            self.player.start()
     
        def set_running_player(self):
            self.play_btn.setEnabled(False)
            self.pause_btn.setEnabled(True)
            self.stop_btn.setEnabled(True)
     
        def pause_preview(self):
            self.player.set_on_pause()
            self.play_btn.setEnabled(True)
            self.pause_btn.setEnabled(False)
            self.start_btn.setFocus(True)
     
        def stop_preview(self):
            self.player.finish()
            self.play_btn.setEnabled(True)
            self.pause_btn.setEnabled(False)
            self.stop_btn.setEnabled(False)
     
        def set_sound_level(self, level):
            self.player.set_sound_level(level)
     
        def update_volume_slider(self, level):
            self.level_lbl.setText(str(level))
            self.level_sld.blockSignals(True)
            self.level_sld.setValue(value)
            self.level_lbl.setText(str(value))
            self.level_sld.blockSignals(False)
     
        def on_video_wheel_event(self, event):
            delta = event.angleDelta().y() / 24
            level = self.level_sld.value() + delta
            self.player.setVolume(level)
            event.accept()
     
    class VideoPlayer(QMediaPlayer):
        def __init__(self, driver):
            super().__init__()
            self.driver = driver
            self.setVideoOutput(driver.player_wdg)
            self.url = None
            self.auto_sound_level = True
            self.is_running = False
            self.is_on_pause = False
            self.volumeChanged.connect(self.on_volume_changed)
            self.stateChanged.connect(self.on_state_changed)
     
        def set_media(self, media):
            if isinstance(media, QUrl):
                self.url = media
     
            elif isinstance(media, str):
                self.url = QUrl(media)
     
            self.setMedia(QMediaContent(self.url))
     
        def start(self):
            self.is_running = True
            self.is_on_pause = False
            self.play()
     
        def set_on_pause(self):
            self.is_running = False
            self.is_on_pause = True
            self.pause()
     
        def finish(self):
            self.is_running = False
            self.is_on_pause = False
            self.stop()
     
        def set_sound_level(self, level):
            self.auto_sound_level = False
            self.setVolume(level)
     
        def on_volume_changed(self, value):
            if self.auto_sound_level:
                self.driver.page.update_volume_slider(value)
            self.auto_sound_level = True
     
        def on_state_changed(self, state):
            if not state:
                self.driver.stop_preview()
     
    if __name__ == "__main__":
        app = QApplication([])
        main = Main()
        main.show()
        main.url_led.setText("https://arteconcert-a.akamaihd.net/am/concert/080000/080200/080206-007-A_EQ_0_VO_03452361_MP4-1500_AMM-CONCERT-NEXT_tjK187zWt.mp4")
        sys.exit(app.exec_())
    J'ai mis une url en exemple, mais il accepte aussi un nom de fichier bien sur.

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    J'ai fait le test avec mon linux mint 18.3 64 bits (en virtuel sur virtualbox avec Windows 10 64 bits), et j'ai eu beaucoup de mal!

    Au début, mon lecteur de radio ne marchait pas avec comme message d'erreur:

    defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.mediaplayer"
    J'ai alors installé tout ce que j'ai pu trouver dans les paquets ayant une relation avec PyQt5 et gstreamer, mais ça ne marchait toujours pas. J'arrivais au bout quand j'ai vu dans un forum la suggestion d'installer "qtmultimedia-examples"! Ce que j'ai fait et...ça marche maintenant!

    C'est manifestement un bug, puisque je n'ai pas installé Qt5...

    @VinsS: ce faisant, ton programme fonctionne parfaitement maintenant!

    Ouf...
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    J'utilise aussi des environnement virtuels, pour tester diverses versions et donc j'installe PyQt5 avec pip. Dans ces cas l'installation semble complète avec tous les modules en un seul package.

  8. #8
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Bistouille n'oublie pas que sous Debian et dérivées PyQt est morcelé en divers packages exemple: python3-pyqt5.qtmultimedia
    Oui, je sais ^^
    Mais j'ai installé PyQt5 via pip pour python3.4 et python3.6, et cela fonctionne parfaitement pour python 3.4 mais pas pour python3.6, mais c'est pas important vu que python3.6 est tout récent.

    Citation Envoyé par tyrtamos Voir le message
    ... quand j'ai vu dans un forum la suggestion d'installer "qtmultimedia-examples"! Ce que j'ai fait et...ça marche maintenant!
    J'avais aussi essayé mais sans résultat, et je précise encore seulement pour python3.6 en 3.4 il n'y a pas cette erreur.
    Le temps ronge l'amour comme l'acide.

Discussions similaires

  1. [2012] Appli basique pour tester une connexion SQL Server
    Par annedeblois dans le forum Outils
    Réponses: 11
    Dernier message: 06/08/2013, 18h55
  2. Lecteur MP3 pour lire une radio en streaming
    Par ginjon dans le forum Débuter
    Réponses: 3
    Dernier message: 09/05/2009, 15h37
  3. [JDBC] pour écouter une table
    Par gocin dans le forum JDBC
    Réponses: 8
    Dernier message: 15/02/2006, 08h26
  4. [JDBC] pour écouter une table
    Par gocin dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 14/02/2006, 20h17
  5. [Batch] Tit prog pour ouvrir une page internet
    Par toniovitch dans le forum Windows
    Réponses: 1
    Dernier message: 17/09/2005, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo