95358


python-vlcを使用して、MediaList内の曲をランダムに再生する方法を探しています。

`random.shuffle`でListを並び替えようとしましたが、  
`random`関数がMediaListに対応していないようで  
`TypeError: 'MediaList' object does not support item assignment`  
と出力され実行できませんでした。

Google等で検索もしてみましたが、望んでいる回答を見つけることができませんでした。

このエラーを治す方法はありますでしょうか？  
もしくは、何か他の良い方法はありますでしょうか？  
よろしくお願いします。

[code]

    import vlc
    import os
    import glob
    import random as rm
    
    pydir=os.path.dirname(__file__)
    os.chdir(pydir)
    files=glob.glob("music/*/*.mp3")
    
    
    instance = vlc.Instance()
    media_list = instance.media_list_new()
    media_list_player = instance.media_list_player_new()
    
    # 曲を追加
    for i ,d in enumerate(files):
        media_list.add_media(d)
    
    rm.shuffle(media_list)
    
    media_list_player.set_media_list(media_list)
    
    a=input()
    
    if a == "normal":
        media_list_player.play()
    elif a == "random":
        ####曲順をシャッフル####
        rm.shuffle(media_list)
        media_list_player.play()
    
[/code]

エラー

[code]

    File "PATH\test.py", line 19, in <module>
        rm.shuffle(media_list)
    File "C:\Users\USER\AppData\Local\Programs\Python\Python311\Lib\random.py", line 383, in shuffle
        x[i], x[j] = x[j], x[i]
        ~^^^
    TypeError: 'MediaList' object does not support item assignment
    
[/code]

**追記**

申し訳ありません、記述不足でした。  
通常の再生順とランダムとを使い分けたいのです。

編集前：

[code]

    media_list_player.play()
    
[/code]

編集後：

[code]

    a=input()
    
    if a == "normal":
        media_list_player.play()
    elif a == "random":
        ####曲順をシャッフル####
        rm.shuffle(media_list)
        media_list_player.play()
    
[/code]


CC BY-SA 4.0
2023-06-24T11:15:09.857
95357
2023-06-24T13:09:53.687
2023-06-24T11:56:55.420
58849
58849
question
python python3 mp3
python-vlcを使用してランダム再生を実現したい


## 基本的な考え方

最終的に「プレイリスト内で曲順がシャッフルされている」事自体がゴールなのであれば、プレイリスト内でシャッフルするのではなく、登録前にファイル一覧をシャッフルするアプローチでも問題ないかなと感じました。  
※python-vlcのMediaListオブジェクトが「`add_media`のたびにファイル名をもとにソートする」ような挙動だと意味はないのですが

### Before:

[code]

    # 曲を追加
    for i ,d in enumerate(files):
        media_list.add_media(d)
    
    rm.shuffle(media_list)
    
[/code]

### after:

[code]

    # 事前にシャッフルしてランダム順序にしておく
    rm.shuffle(files)
    
    # 曲を追加
    for i ,d in enumerate(files):
        media_list.add_media(d)
    
    
[/code]

## 追記を受けて

[python-vlcのAPIドキュメント](https://www.olivieraubert.net/vlc/python-
ctypes/doc/)を読む限り、MediaListクラスには`__getitem__`はあっても`__setitem__`はありません。（これが理由で質問のエラーが出ている認識）

そのため、python-vlcとして「MediaList内にあるメディアの順序をランダム化する」アプローチの存在には期待しないほうが良さそうです。  
※一応、`insert_media`, `remove_media`を使えば擬似的に実現できるかもしれないが、自分の中ではあまり意義がない

また、`input()`の入力を前提をしていることから、現時点ではこのファイル単体で再生が出来れば良いものとすると、  
回答としての考え方は特に変わらず、やっぱりアプローチとしては下記のとおりとなります。

  * MediaListに追加する前にシャッフルする
  * 入力内容でシャッフル実行の有無を決める
  * python-vlc上の操作でのランダム再生には期待しない

### 上記の考え方をもとに処理を並び替える一例

[code]

    import vlc
    import os
    import glob
    import random as rm
    
    pydir=os.path.dirname(__file__)
    os.chdir(pydir)
    files=glob.glob("music/*/*.mp3")
    
    a=input()
    
    if a == "normal":
        pass
    elif a == "random":
        ####曲順をシャッフル####
        rm.shuffle(files)
    
    instance = vlc.Instance()
    
    # MediaListを用意して曲を追加
    media_list = instance.media_list_new()
    for i ,d in enumerate(files):
        media_list.add_media(d)
    
    # MediaListPlayerで再生
    media_list_player = instance.media_list_player_new()
    media_list_player.set_media_list(media_list)
    media_list_player.play()
    
[/code]


CC BY-SA 4.0
2023-06-24T11:40:31.800
95358
2023-06-24T13:09:53.687
2023-06-24T13:09:53.687
2784
2784
95357
answer