python:python-vlc

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
python:python-vlc [2021/05/21 05:56] – [メディアリストのループ再生] ともやんpython:python-vlc [2021/06/20 06:16] (現在) – [Python 製コマンドライン VLC プレイヤー] ともやん
行 1: 行 1:
-<html> +====== python-vlc - VLC の Python バインディング ======
-  <style> +
-    #result pre { +
-      /*height: 200px;*/ +
-      overflow: scroll; +
-      overflow-x: hidden; +
-      font-size: 10px; +
-    } +
-  </style> +
-</html> +
-====== python-vlc ======+
 {{linux:vlc-player_icon.jpg?250|リアル世界でのVLC}}\\ {{linux:vlc-player_icon.jpg?250|リアル世界でのVLC}}\\
 ごめんなさい🙏ブラ男氏が縄張りを主張しちゃいました🐶😅💦\\ ごめんなさい🙏ブラ男氏が縄張りを主張しちゃいました🐶😅💦\\
行 18: 行 8:
 ===== インストール ===== ===== インストール =====
 <code powershell> <code powershell>
-pip install python-vlc+$ python3 -m venv py3_vlc 
 +$ . py3_vlc/bin/activate 
 +(py3_vlc) $ pip install python-vlc
 </code> </code>
 <WRAP prewrap 100% #result> <WRAP prewrap 100% #result>
行 30: 行 22:
 </WRAP> </WRAP>
  
-===== メディアリストループ再生 =====+===== Python 製コマンドライン VLC プレイヤー ===== 
 +メディアリストループ再生するサンプルコードである。\\ 
 +VLC インスタンスは Raspberry Pi をヘッドレスで運用すること前提に <html><code>'--no-video'</code></html> オプションを指定しているので、必要に応じてインスタンスの起動オプションを修正してください。\\
 <WRAP prewrap 100% #mincode> <WRAP prewrap 100% #mincode>
-<code python>+<code python pyvlcplayer.py>
 #!/usr/bin/env python #!/usr/bin/env python
 # -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
行 38: 行 32:
 import vlc import vlc
 import os import os
-from os.path import expanduser 
-import mutagen 
 import pathlib import pathlib
 import readline import readline
  
 # 拡張子は小文字で定義 !! # 拡張子は小文字で定義 !!
-#exts = ('.mp3', '.m4a', '.wav', '.wma', '.mpg', '.mov', '.mkv', '.mp4', '.webm'+exts = ('.mp3', '.m4a', '.wav', '.wma', '.mpg', '.mov', '.mkv', '.mp4', '.webm'
-exts = ('.mp3', '.m4a', '.flac', '.wav')+#exts = ('.mp3', '.m4a', '.flac', '.wav')
  
-PATH = '/var/samba/DataShare/WinAmpData/TRF'+HOME os.path.expanduser('~'
 +READLINE_HISTORY_FILE = '.pyvlcplayer_history' 
 +READLINE_HISTORY_PATH = os.path.join(HOME, READLINE_HISTORY_FILE) 
 +EQ_PRESET_BASS_BOOST = [14.5, 15.5, 10.5, 9.3, 10.8, 15.3, 0.0, 2.2, 7.8, 14.6]
  
-READLINE_HISTORY_FILE expanduser('~/.pyvlcplayer_history'+PATH = '/var/samba/MusicData/TRF'
-EQ_PRESET_BASE_BOOST = [20.0, 10.5, 2.8, 9.3, 14.8, 6.3, 0.0, 2.2, 7.8, 15.6]+
  
 def walk(dir, exts): def walk(dir, exts):
行 63: 行 57:
     return result     return result
  
-def printVLCMeta(media):+def printVLCMeta(media, path):
     title = media.get_meta(vlc.Meta.Title)     title = media.get_meta(vlc.Meta.Title)
     artist = media.get_meta(vlc.Meta.Artist)     artist = media.get_meta(vlc.Meta.Artist)
行 73: 行 67:
     genre = media.get_meta(vlc.Meta.Genre)     genre = media.get_meta(vlc.Meta.Genre)
     #url = media.get_meta(vlc.Meta.URL)     #url = media.get_meta(vlc.Meta.URL)
 +    fileSize = os.path.getsize(path)
  
     print(f'Album: {album}')     print(f'Album: {album}')
     print(f'Title: {title}')     print(f'Title: {title}')
 +    print(f'File Size: {fileSize:,} bytes')
     print(f'Artist: {artist}')     print(f'Artist: {artist}')
     print(f'Genre: {genre} Track: {trackNumber: >3}/{trackTotal}')     print(f'Genre: {genre} Track: {trackNumber: >3}/{trackTotal}')
 +    print(f'Path: {path}')
     #print(f'URL: {url}')     #print(f'URL: {url}')
  
 def main(): def main():
 +    pathlib.Path(READLINE_HISTORY_PATH).touch()
 +    readline.read_history_file(READLINE_HISTORY_PATH)
 +    
 +    flagEQ = False
 +
     medias = walk(PATH, exts)     medias = walk(PATH, exts)
     medias.sort()     medias.sort()
     print(f'Media Count: {len(medias)}')     print(f'Media Count: {len(medias)}')
  
-    mediaList = vlc.MediaList()+    # No Video mode for headless Raspberry Pi 
 +    vlcInstance = vlc.Instance('--no-video'
 + 
 +    #mediaList = vlc.MediaList() 
 +    mediaList = vlcInstance.media_list_new()
  
     for index, media in enumerate(medias):     for index, media in enumerate(medias):
         print(f'Index: {index: >4} Path: {media}')         print(f'Index: {index: >4} Path: {media}')
-        mediaList.add_media(media)+        mediaList.add_media(os.path.join(media[0], media[1])) 
 + 
 +    #mediaListPlayer = vlc.MediaListPlayer() 
 +    mediaListPlayer = vlcInstance.media_list_player_new()
  
-    mediaListPlayer = vlc.MediaListPlayer() 
     mediaListPlayer.set_media_list(mediaList)     mediaListPlayer.set_media_list(mediaList)
     mediaListPlayer.set_playback_mode(vlc.PlaybackMode.loop)     mediaListPlayer.set_playback_mode(vlc.PlaybackMode.loop)
行 97: 行 105:
  
     mediaPlayer = mediaListPlayer.get_media_player()     mediaPlayer = mediaListPlayer.get_media_player()
-    mediaPlayer.audio_set_volume(30)+ 
 +    print('🎊🎂🍩🍩🍩 libvlc information 🍩🍩🍩🎂🎊'
 +    print(f"libvlc version: '{vlc.libvlc_get_version().decode()}' ✨"
 +    print(f"libvlc compiler version: '{vlc.libvlc_get_compiler().decode()}' ✨"
 +    print(f"libvlc changeset: '{vlc.libvlc_get_changeset().decode()}' ✨\n")
  
     while True:     while True:
         print('po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT')         print('po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT')
-        data = input()+        print('eq [frequency band value list]: Equalizer On/Off'
 +        # 入力待ちプロンプト 
 +        data = input('>> ')
  
         #POSITION         #POSITION
行 111: 行 125:
         elif data == 'i':         elif data == 'i':
             media = mediaPlayer.get_media()             media = mediaPlayer.get_media()
-            path = media.get_mrl() 
-            #ft = mutagen.File(path) 
-            #title = ft['title'] 
             index = mediaList.index_of_item(media)             index = mediaList.index_of_item(media)
 +            path = os.path.join(medias[index][0], medias[index][1])
             print(f'Index: {index}')             print(f'Index: {index}')
-            printVLCMeta(media)+            printVLCMeta(media, path)
  
         #PREVIOUS         #PREVIOUS
行 143: 行 155:
                 eqAmps = list(map(float, data[3:].split()))                 eqAmps = list(map(float, data[3:].split()))
                 if len(eqAmps) == 0:                 if len(eqAmps) == 0:
-                    eqAmps = EQ_PRESET_BASE_BOOST+                    eqAmps = EQ_PRESET_BASS_BOOST
                                  
                 bandCount = vlc.libvlc_audio_equalizer_get_band_count()                 bandCount = vlc.libvlc_audio_equalizer_get_band_count()
行 171: 行 183:
         elif data == 'q':         elif data == 'q':
             mediaListPlayer.stop()             mediaListPlayer.stop()
 +            readline.write_history_file(READLINE_HISTORY_PATH)
             print('Quit.')             print('Quit.')
-            readline.write_history_file(READLINE_HISTORY_FILE) 
             break             break
  
行 179: 行 191:
 </code> </code>
 </WRAP> </WRAP>
-*** os.walk() に followlinks=True オプションを追加。(シンボルリンクを辿るように指定)**\\+ 
 +===== 使い方 ===== 
 +**os.walk() に followlinks=True オプションを追加。(シンボルリンクを辿るように指定)**\\ 
 +**eq** で VLC のイコライザーを設定。\\ 
 +<WRAP prewrap 100% #mincode> 
 +<code> 
 +eq <- イコライザー Off の場合は EQ_PRESET_BASS_BOOST で On にする。 
 +Band Count: 10 
 +Freq: 31.25 62.5 125.0 250.0 500.0 1000.0 2000.0 4000.0 8000.0 16000.0 
 +Amp: 20.0 10.5 2.8 9.3 14.8 6.3 0.0 2.2 7.8 15.6 
 +Equalizer: On 
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +eq 20 20 20 <- イコライザー 30Hz 60Hz 125Hz を 20.0 dB に設定する。 
 +Band Count: 10 
 +Freq: 31.25 62.5 125.0 250.0 500.0 1000.0 2000.0 4000.0 8000.0 16000.0 
 +Amp: 20.0 20.0 20.0 
 +Equalizer: On 
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +eq <- イコライザー On の場合は Off にする。 
 +Equalizer: Off 
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +</code> 
 +</WRAP> 
 + 
 +**Raspberry Pi** をヘッドレスで運用している場合は以下のエラーで動作が不安定になる場合がある。\\ 
 +<html> 
 +<div id="ncolor_result"> 
 +<pre> 
 +>> [<b class=GRN>01f70530</b>] gles2 generic error: <b class=RED>parent window not available</b> 
 +[<b class=GRN>01f6fe70</b>] mmal_xsplitter vout display error: <b class=RED>Failed to open Xsplitter:opengles2 module</b> 
 +[<b class=GRN>01f70530</b>] xcb generic error: <b class=RED>window not available</b> 
 +[<b class=GRN>01f6fe70</b>] mmal_xsplitter vout display error: <b class=RED>Failed to open Xsplitter:xcb_x11 module</b> 
 +
 +Index: 0 
 +Album: None 
 +Title: Hello Kiss me No say-a2ZaDrdpwMk.webm 
 +File Size: 23,840,020 bytes 
 +Artist: None 
 +Genre: None Track:   0/0 
 +Path: /var/samba/DataShare/02_YouTubeDLs/05_ぜんぶ君のせいだ。/20160127_A01st_やみかわIMRAD/Hello Kiss me No say-a2ZaDrdpwMk.webm 
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +>> q 
 +Quit. 
 +</pre> 
 +</div> 
 +</html> 
 + 
 +Python コードを以下のように VLC インスタンスのオプションに <html><code>'--no-video'</code></html> を指定して、ビデオ出力を無効にする。\\ 
 +<WRAP prewrap 100% #mincode> 
 +<code python> 
 +    medias = walk(PATH, exts) 
 +    medias.sort() 
 +    print(f'Media Count: {len(medias)}'
 + 
 +    # No Video mode for headless Raspberry Pi 
 +    vlcInstance = vlc.Instance('--no-video'
 + 
 +    #mediaList = vlc.MediaList() 
 +    mediaList = vlcInstance.media_list_new() 
 + 
 +    for index, media in enumerate(medias): 
 +        print(f'Index: {index: >4} Path: {media}'
 +        mediaList.add_media(os.path.join(media[0], media[1])) 
 + 
 +    #mediaListPlayer = vlc.MediaListPlayer() 
 +    mediaListPlayer = vlcInstance.media_list_player_new() 
 + 
 +    mediaListPlayer.set_media_list(mediaList) 
 +    mediaListPlayer.set_playback_mode(vlc.PlaybackMode.loop) 
 +    mediaListPlayer.play() 
 +</code> 
 +</WRAP> 
 + 
 +<html> 
 +<div id="ncolor_result"> 
 +<pre> 
 +Index:   95 Path: ('/var/samba/DataShare/02_YouTubeDLs/05_ぜんぶ君のせいだ。/20210603_ARe04_Q.E.D. bi', '13.ぜんぶ君のせいだ。あおはる-hNuG-hrxzMY.mkv'
 +Index:   96 Path: ('/var/samba/DataShare/02_YouTubeDLs/05_ぜんぶ君のせいだ。/20210603_ARe04_Q.E.D. bi', '14.ぜんぶ君のせいだ。独唱無題-rBeoKrJFkb0.mkv'
 +Index:   97 Path: ('/var/samba/DataShare/02_YouTubeDLs/05_ぜんぶ君のせいだ。/20210603_ARe04_Q.E.D. bi', '15.ぜんぶ君のせいだ。無題合唱-N9tuj3sHMXI.mkv'
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +>> i 
 +Index: 2 
 +Album: None 
 +Title: ぜんぶ君のせいだ。「ShitEndプラシーボ」Official MusicVideo-1CsCYcTF9w4.mp4 
 +File Size: 64,454,373 bytes 
 +Artist: None 
 +Genre: None Track:   0/0 
 +Path: /var/samba/DataShare/02_YouTubeDLs/05_ぜんぶ君のせいだ。/20160127_A01st_やみかわIMRAD/ぜんぶ君 
 +のせいだ。「ShitEndプラシーボ」Official MusicVideo-1CsCYcTF9w4.mp4 
 +po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT 
 +eq [frequency band value list]: Equalizer On/Off 
 +>> 
 +</pre> 
 +</div> 
 +</html>
  
 ===== 参考文献 ===== ===== 参考文献 =====
行 185: 行 296:
 [[https://stackoverflow.com/questions/28440708/python-vlc-binding-playing-a-playlist/33042754|mp3 - Python VLC binding- playing a playlist - Stack Overflow]]\\ [[https://stackoverflow.com/questions/28440708/python-vlc-binding-playing-a-playlist/33042754|mp3 - Python VLC binding- playing a playlist - Stack Overflow]]\\
 [[https://jellyware.jp/kurage/raspi/python_vlc.html|python-vlcで音楽再生をプログラム制御]]\\ [[https://jellyware.jp/kurage/raspi/python_vlc.html|python-vlcで音楽再生をプログラム制御]]\\
 +
 +==== 付録 ====
 +[[tw>tomoyan596/status/1395470176062115842|あんまし直してる暇も無いので、python-vlcでテキトーに作ったコマンドラインプレーヤーにイコライザーのセットコマンドをテキトーに追加してます😅💦 / Twitter]]\\
 +[[tw>tomoyan596/status/1401229926762614785|Python製のVLCコマンドラインプレイヤーを、Raspberry Pi Zeroでヘッドレス運用すると、動画データを含む場合にエラーを起こして動作が不安定になっていたので、ビデオ出力を無効化してオーディオ再生できるようにしました😊 / Twitter]]\\
  
  • python/python-vlc.1621544163.txt.gz
  • 最終更新: 2021/05/21 05:56
  • by ともやん