Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
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
Archives
Today
Total
관리 메뉴

yongsa0221의 고물상

Yt-dlp를 사용한 라즈베리파이 프로젝트 -완- 본문

예토전생

Yt-dlp를 사용한 라즈베리파이 프로젝트 -완-

yongsa0221 2024. 9. 2. 18:11

프로젝트 동작 구조

완성된 프로젝트는 다음과 같이 동작한다.

 

provider - consumer 관계로 접근하여 구현하려고 하였다.

사용자의 입력을 provider, 이에 따라 동작할 애플리케이션을 consumer로 생각하고 구조를 잡았다.

이벤트 기반의 프로그래밍을 참고하여 리스너와 핸들러를 구현하는 방식으로 진행하였다.

 

사용자 입력에 따라 메시지가 BlockingQueue를 사용하여 입력되며 리스너는 이 큐에 있는 사용자 입력에 따른 메시지를 소비하여 핸들러에게 전달하는 구조이다.  

public class StateMessageQueue {
    private BlockingQueue<StateMessage> queue;
    public StateMessageQueue() {
        this.queue = new LinkedBlockingQueue<>();
    }

    public boolean offer(StateMessage message) {
        return queue.offer(message);
    }

    public StateMessage poll(int time, TimeUnit timeunit) throws InterruptedException {
        return queue.poll(time, timeunit);
    }
}
public class StateMessageListener implements Runnable {
    private final StateMessageQueue queue;
    private final StateMessageHandler handler;
    private final RunFlag flag;
    private boolean runnable = true;

    @Autowired
    public StateMessageListener(StateMessageQueue queue, StateMessageHandler handler, RunFlag flag) {
        this.queue = queue;
        this.handler = handler;
        this.flag = flag;
    }

    @Override
    public void run() {
        while (runnable) {
            synchronized (queue) {
                try {
                    queue.wait();
                    StateMessage message = queue.poll(3, TimeUnit.SECONDS);
                    runnable = handler.handle(message);
                    synchronized (flag) {
                        if (!runnable) {
                            flag.setFalse();
                        }
                        flag.notifyAll();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        System.out.println(this.toString() + "terminated");
    }
@Autowired
    public StateMessageHandler(YoutubeMusicPlayer musicPlayer, YoutubeAudioSearcher searcher, CactusController cactus) {
        this.musicPlayer = musicPlayer;
        this.searcher = searcher;
        this.cactus = cactus;
    }

    public boolean handle(StateMessage stateMessage) {
        State state = stateMessage.getState();
        String value = stateMessage.getValue();
        System.out.println(value);
        switch (state) {
            case PLAY -> {
                YoutubeAudio audio = searcher.getYoutubeAudioFrom(value);
                musicPlayer.downLoadAndPlay(audio);
                cactus.dance();
            }
            case STOP -> {
                musicPlayer.stopMusic();
                cactus.stop();
            }
            case PAUSE -> {
                musicPlayer.pauseMusic();
                cactus.stop();
            }
            case RESUME -> {
                musicPlayer.resumeMusic();
                cactus.dance();
            }
            case VOLUME -> {
                if (value.equals("up")) {
                    musicPlayer.volumeUp();
                } else if (value.equals("down")) {
                    musicPlayer.volumeDown();
                } else {
                    musicPlayer.setVolumeLevel(value);
                }
            }
            case EXIT -> {
                musicPlayer.stopMusic();
                cactus.stop();
                cactus.close();
                return false;
            }
        }
        return true;
    }

 

 

 

하드웨어

프로젝트에 사용한 장난감은 aliexpress에서 구매하였다.

 

선인장 해체하는 모습

 

선인장을 무자비하게 해체한 후 필요한 부분만 사용한다.

사용할 기능

선인장 장난감의 뇌와 같은 역할을 하는 기판을 제거해주고 라즈베리 파이만 달면 된다. 선인장 내장 스피커는 음질이 너무 구려 따로 외부 스피커를 사용하였다.

 

 

 DC모터를 사용하기 위해서는 따로 모터 드라이버를 사용해야 하는데 쿠팡에서 구매해서 달아주었다.

DC모터 L298N 모터드라이버

녀석의 정확한 이름은 L298N 듀얼 H-브릿지 모터 드라이버 모듈. DC모터 제어 가능하게 하며 쿠팡에서 약 3000원 주고 구매했다. aliexpress에선 276원에도 구매 가능하다.

아두이노 용으로 나와있으며 라즈베리파이에서도 gpio를 통해 제어가 가능하다. PWM 제어를 통해 모터속도 제어 가능하다.

 

 

연결된 모습

회로 구성은 위의 사진과 같이 되어있으며 음성출력은 라즈베리파이의 자체 오디오 단자를 통해 출력한다.

 

영상

 

계획한 부분을 모두 구현하지는 못했지만 진행하며 여러모로 공부도 많이 되었던 프로젝트이다

웹이 아닌 다른 플랫폼에서 spring을 사용해보았던 것이 여러모로 인상깊었던 프로젝트

그러나 처음 해보는 만큼 정신나간 짓도 많이 해서 개인적으로 아쉬운 프로젝트이다.

 

나중에 리팩터링 한다면

gpt function 을 사용해서 자연어 음성 명령을 통해 제어하는 것과

파이썬을 아예 사용하지 않고 스트리밍할 수  있는 방법을 찾아보는 것

두가지 정도...