文書の過去の版を表示しています。
python-vlc - VLC の Python バインディング
本家: Python bindings for VLC
ドキュメント: API Documentation
インストール
$ python3 -m venv py3_vlc $ . py3_vlc/bin/activate (py3_vlc) $ pip install python-vlc
Collecting python-vlc Downloading python_vlc-3.0.7110-py3-none-any.whl (80 kB) |████████████████████████████████| 80 kB 721 kB/s Installing collected packages: python-vlc Successfully installed python-vlc-3.0.7110
Python 製コマンドライン VLC プレイヤー
メディアリストをループ再生するサンプルコードである。
VLC インスタンスは Raspberry Pi をヘッドレスで運用すること前提に '--no-video'
オプションを指定しているので、必要に応じてインスタンスの起動オプションを修正してください。
- pyvlcplayer.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import vlc import os import pathlib import readline # 拡張子は小文字で定義 !! exts = ('.mp3', '.m4a', '.wav', '.wma', '.mpg', '.mov', '.mkv', '.mp4', '.webm') #exts = ('.mp3', '.m4a', '.flac', '.wav') 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] PATH = '/var/samba/MusicData/TRF' def walk(dir, exts): result = [] for path, dirs, files in os.walk(os.path.join(dir, '.'), followlinks=True): for file in files: #print(file) if file.lower().endswith(exts): dir_path = os.path.abspath(path) result.append(os.path.join(dir_path, file)) return result def printVLCMeta(media, path): title = media.get_meta(vlc.Meta.Title) artist = media.get_meta(vlc.Meta.Artist) album = media.get_meta(vlc.Meta.Album) trackNumber = media.get_meta(vlc.Meta.TrackNumber) trackNumber = trackNumber if not trackNumber is None else 0 trackTotal = media.get_meta(vlc.Meta.TrackTotal) trackTotal = trackTotal if not trackTotal is None else 0 genre = media.get_meta(vlc.Meta.Genre) #url = media.get_meta(vlc.Meta.URL) fileSize = os.path.getsize(path) print(f'Album: {album}') print(f'Title: {title}') print(f'File Size: {fileSize:,} bytes') print(f'Artist: {artist}') print(f'Genre: {genre} Track: {trackNumber: >3}/{trackTotal}') print(f'Path: {path}') #print(f'URL: {url}') def main(): pathlib.Path(READLINE_HISTORY_PATH).touch() readline.read_history_file(READLINE_HISTORY_PATH) flagEQ = False 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() mediaPlayer = mediaListPlayer.get_media_player() while True: print('po: POSITION, i: INDEX/Info, p: PREVIOUS, n: NEXT, q: QUIT') print('eq [frequency band value list]: Equalizer On/Off') # 入力待ちプロンプト data = input('>> ') #POSITION if data == 'po': pos = mediaPlayer.get_position() print(f'Position: {pos}') #INDEX/Info elif data == 'i': media = mediaPlayer.get_media() index = mediaList.index_of_item(media) path = os.path.join(medias[index][0], medias[index][1]) print(f'Index: {index}') printVLCMeta(media, path) #PREVIOUS elif data == 'p': mediaListPlayer.previous() media = mediaPlayer.get_media() index = mediaList.index_of_item(media) fileName = media.get_meta(0) print(f'Previous -> Current Index: {index} File: {fileName}') #NEXT elif data == 'n': mediaListPlayer.next() media = mediaPlayer.get_media() index = mediaList.index_of_item(media) fileName = media.get_meta(0) print(f'Next -> Current Index: {index} File: {fileName}') #Set Equalizer elif data.startswith('eq'): #EQ Set if len(data) > 3 or not flagEQ: flagEQ = True eqFreqs = [] eqAmps = list(map(float, data[3:].split())) if len(eqAmps) == 0: eqAmps = EQ_PRESET_BASS_BOOST bandCount = vlc.libvlc_audio_equalizer_get_band_count() print(f'Band Count: {bandCount}') eq = vlc.AudioEqualizer() for bandIndex in range(bandCount): try: amp = eqAmps[bandIndex] except IndexError: amp = 0 eq.set_amp_at_index(amp, bandIndex) eqFreqs.append(vlc.libvlc_audio_equalizer_get_band_frequency(bandIndex)) print(f'Freq: {" ".join(map(str, eqFreqs))}') print(f'Amp: {" ".join(map(str, eqAmps))}') #EQ Off elif flagEQ: flagEQ = False eq = None print(f'Equalizer: {"On" if flagEQ else "Off"}') mediaPlayer.set_equalizer(eq) #QUIT elif data == 'q': mediaListPlayer.stop() readline.write_history_file(READLINE_HISTORY_PATH) print('Quit.') break if __name__ == '__main__': main()
使い方
os.walk() に followlinks=True オプションを追加。(シンボルリンクを辿るように指定)
eq で VLC のイコライザーを設定。
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
Raspberry Pi をヘッドレスで運用している場合は以下のエラーで動作が不安定になる場合がある。
>> [01f70530] gles2 generic error: parent window not available [01f6fe70] mmal_xsplitter vout display error: Failed to open Xsplitter:opengles2 module [01f70530] xcb generic error: window not available [01f6fe70] mmal_xsplitter vout display error: Failed to open Xsplitter:xcb_x11 module i 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.
Python コードを以下のように VLC インスタンスのオプションに '--no-video'
を指定して、ビデオ出力を無効にする。
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()
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 >>
参考文献
python - FileNotFoundError: Could not find module 'libvlc.dll' - Stack Overflow
mp3 - Python VLC binding- playing a playlist - Stack Overflow
python-vlcで音楽再生をプログラム制御