상세 컨텐츠

본문 제목

파이썬으로 VLC미디어플레이어 컨트롤하기 고급편

본문

2021.05.03 - [강의강좌 정리/파이썬 YouTube 뮤직 플레이어 개발강좌] - 파이썬으로 VLC미디어플레이어를 컨트롤 하기

scv-life.tistory.com/106

 

파이썬으로 VLC미디어플레이어를 컨트롤 하기

이전글: scv-life.tistory.com/105 파이썬과 VLC 미디어 플레이어 VLC 미디어 플레이어 VLC 미디어 플레이어를 아시나요? VLC는 VideoLAN 프로젝트에서 개발한 무료 오픈소스 크로스플랫폼의 미디어 플레이어

scv-life.tistory.com

이전 강좌에서는 파이썬으로 VLC 미디어플레이어를 컨트롤 할 수 있는 python-vlc의 기본적인 메소드들에 대해 알아봤습니다.

 

이번 강좌에서는 좀 더 심층적인 python-vlc 사용법과 media의 정보를 추출하는 방법에 대해 알아보겠습니다.

 

VlcPlayer 클래스

이전 강의에서 설명했던 각종 컨트롤메소들을 VlcPlayer라는 하나의 클래스에 담아 봤습니다.

(지속적으로 설명해야 하는데 코드가 중복적으로 길어져서 클래스화 했어요..^^)

import vlc


class VlcPlayer:
    '''
    args: VLC인스턴스 생성옵션
    '''
    
    def __init__(self, *args):
        if args:
            instance = vlc.Instance(*args)
            self.media = instance.media_player_new()
        else:
            self.media = vlc.MediaPlayer()

    def set_uri(self, mrl):
        '''
        스트리밍 url주소 또는 로컬 재생파일을 설정
        :param mrl: 스트리밍주소
        :return:
        '''
        self.media.set_mrl(mrl)

    def play(self, path=None):
        '''
        미디어 재생
        :param path:
        :return: 성공:0, 실패:-1
        '''
        if path:
            self.set_uri(path)
            return self.media.play()
        else:
            return self.media.play()

    def pause(self):
        '''
        재생 멈춤
        :return:
        '''
        self.media.pause()

    def resume(self):
        '''
        재생 다시 시작
        :return:
        '''
        self.media.set_pause(0)

    def stop(self):
        '''
        재생 멈춤
        :return:
        '''
        self.media.stop()

    def release(self):
        '''
        미디어 소스 초기화
        :return:
        '''
        return self.media.release()

    def is_playing(self):
        '''
        플레이 상태 확인
        :return: 재생중 : 1, 재생중이지 않음 : 0
        '''
        return self.media.is_playing()

    def get_time(self):
        '''
        Elapsed time, return millisecond value
        :return:
        '''
        return self.media.get_time()

    def set_time(self, ms):
        '''
        미디어 특정시간으로 이동.
        :param ms:
        :return: 성공 : 0, 실패 : -1
        '''
        return self.media.get_time(ms)

    # The total length of audio and video, returns the value in milliseconds
    def get_length(self):
        '''
        미디어소스의 재생길이
        :return: 재생길이(ms)
        '''
        return self.media.get_length()

    def get_volume(self):
        '''
        :return: 현재 볼륨 상태 값 (0~100)
        '''
        return self.media.audio_get_volume()

    def set_volume(self, volume):
        '''
        볼륨 설정
        :param volume: 0~100 사이 값
        :return:
        '''
        return self.media.audio_set_volume(volume)

    # Return to the current state: playing; paused; other
    def get_state(self):
        '''
        현재 플레이어 상태 확인
        :return: playing : 1, paused : 0, 그외 -1
        '''
        state = self.media.get_state()
        if state == vlc.State.Playing:
            return 1
        elif state == vlc.State.Paused:
            return 0
        else:
            return -1

    def get_position(self):
        '''
        현재 playback 진척도
        :return: 미디어의 재생율 (1 이하 소숫점)
        '''
        return self.media.get_position()

    def set_position(self, float_val):
        '''
        특정 재생율로 미디어의 재생위치를 변경.
        :param float_val: 0~1 사이 float값
        :return:
        '''
        return self.media.set_position(float_val)

    def get_rate(self):
        '''
        :return: 재생속도
        '''
        return self.media.get_rate()

    def set_rate(self, rate):
        '''
        재생속도 설정
        :param rate: 배속
        :return:
        '''
        return self.media.set_rate(rate)

    def set_ratio(self, ratio):
        '''
        Set the aspect ratio (such as "16:9", "4:3")
        :param ratio:
        :return:
        '''
        # Must be set to 0, otherwise the screen width and height cannot be modified
        self.media.video_set_scale(0) 
        self.media.video_set_aspect_ratio(ratio)

    def add_callback(self, event_type, callback):
        '''
        콜백 listener 설정
        :param event_type: vlc listener 환경변수
        :param callback: 콜백함수
        :return:
        '''
        self.media.event_manager().event_attach(event_type, callback)

    def remove_callback(self, event_type, callback):
        '''
        Remove listener
        :param event_type:
        :param callback:
        :return:
        '''
        self.media.event_manager().event_detach(event_type, callback)

 

콜백 함수를 이용한 이벤트 처리

재생이 시작/멈추하거나 vlc 미디어플레이어를 컨트롤을 할때마다 특정 함수를 실행할 수 있도록 하는 이벤트처리 VLC listener에 대해 알아보겠습니다.

 

이전 강좌에서는 vlc player()가 time.sleep 만큼 플레이되고 곧바로 종료되는 현상을 확인하셨을 껍니다.

 

이 현상은 vlc player()가 비동기적으로 처리되기 때문에 프로그램코드가 종료되지 않을때까지 플레이할 수 있도록 테스트를 위해 특정 시간동안만 플레이 될수 있도록 time.sleep(초)만큼 설정해준 것이라 보시면 됩니다.

 

그렇다면 방탄소년단의 MV 영상이 종료되기 전까지 지속적으로 플레이할 수 있도록 하기 위해서는 어떻게 해야할까요?

 

바로 for 또는 while 구문과 같은 루프구문이 뮤비가 종료될때까지 계속 구동되어야 할 것입니다. 하지만 어떻게 영상의 종료시점을 알 수 있을까요? 

 

이와 관련해 VLC 모듈은 다음과 같은 이벤트 시그널을 제공해주고 있습니다.

  • MediaPlayerNothingSpecial: vlc is idle, just waiting to issue a command
  • MediaPlayerOpening: vlc is opening the media resource locator (MRL)
  • MediaPlayerBuffering (int cache): vlc is buffering
  • MediaPlayerPlaying: vlc is playing media
  • MediaPlayerPaused: vlc is paused
  • MediaPlayerStopped: vlc is in a stopped state
  • MediaPlayerForward: vlc fast forward through media (this will never be called)
  • MediaPlayerBackward: vlc is rewinding (this will never be called)
  • MediaPlayerEncounteredError: vlc encountered an error and cannot continue
  • MediaPlayerEndReached: vlc has reached the end of the current playlist
  • MediaPlayerTimeChanged: Time has changed
  • MediaPlayerPositionChanged: The progress has changed
  • MediaPlayerSeekableChanged: Whether the searchable state of the streaming media has changed (true means searchable, false means not searchable)
  • MediaPlayerPausableChanged: Whether the media can be paused or not (true means it can be paused, false means it cannot be paused)
  • MediaPlayerMediaChanged: The media has changed
  • MediaPlayerTitleChanged: The title has changed (DVD/Blu-ray)
  • MediaPlayerChapterChanged: Chapter changed (DVD/Blu-ray)
  • MediaPlayerLengthChanged: (Only for Mozilla in vlc version <2.2.0) length has changed
  • MediaPlayerVout: The number of video outputs has changed
  • MediaPlayerMuted: Mute
  • MediaPlayerUnmuted: Unmute
  • MediaPlayerAudioVolume: The volume has changed

다음 예제는 vlc의 여러 이벤트중 MediaPlayerStopped를 이용하여 다음과 같이 뮤비 플레이가 종료되는 순간 프로그램도 종료될 수 있도록 하는 스크립트를 만들었습니다.

def my_call_back(event):
    print("콜백함수호출: 종료호출")
    global status 
    status = 1 

if "__main__" == __name__:

    # 뮤직비디오 파일
    media_file = "BTS Dynamite MV.mp4"

    player = VlcPlayer()
    player.add_callback(vlc.EventType.MediaPlayerStopped, my_call_back)

    player.play(media_file)
    player.set_position(0.9) #테스트를 위해 영상의 90%위치로 이동시킵니다.
    player.set_rate(2) # 재생속도를 2배속으로 설정합니다.

    status = 0
    while True:
        if status == 1:
            break
        else:
            pass

 

Audio visualiztion

vlc 인스턴스를 생성할때 옵션을 설정할 수 있습니다.

vlc 옵션에는 여러가지 기능이 있는데, 이중 오디오 시각화 옵션에 대해 알아보겠습니다. (음악플레이어를 만들때 좋겠죠?)

 

참조: wiki.videolan.org/VLC_command-line_help/

 

VLC command-line help - VideoLAN Wiki

Running the command vlc --help will create a .TXT file containing all the command-line options. You can also use this to get more exhaustive list: vlc -H If you look for help, on a particular module, you can also use vlc -p module --advanced --help-verbose

wiki.videolan.org

 

위 예제의 인스턴스 생성부분과 관련하여 다음과 같이 옵션을 주고 생성해주면 됩니다.

if "__main__" == __name__:

    # 뮤직비디오 파일
    media_file = "BTS Dynamite MV.mp4"

    player = VlcPlayer("--audio-visual=visual",
                       "--effect-list=spectrum", "--effect-fft-window=flattop")
    player.add_callback(vlc.EventType.MediaPlayerStopped, my_call_back)

    player.play(media_file)
    player.set_position(0.9) #테스트를 위해 영상의 90%위치로 이동시킵니다.

    status = 0
    while True:
        if status == 1:
            break
        else:
            pass

실행결과

 

위 예제의 옵션 중 '--effect-list=<string>'의 문자열값은 dummy, scope, spectrum, spectrometer, vuMeter 중에 하나의 값을 선택하면 됩니다. 

 

그리고 --effect-fft-window 옵션의 값은 hann, flattop, blackmanharris, kaiser 이 리스트 중 하나의 값을 선택하여 설정해주시면 됩니다.

 

 

지금까지 python-vlc 모듈 사용에 대한 강좌를 마치도록 하겠습니다.

관련글 더보기

댓글 영역