我正在嘗試使用流構建播放器。主要思想是讓一個執行緒運行一個播放器,該播放器讀取來自另一個同時下載 youtube 音頻的執行緒的位元組。該代碼作業了一段時間并且內容正確流式傳輸,但幾秒鐘后我總是收到此錯誤:
Exception: fd:13: hPutBuf: resource vanished (Broken pipe).
我想我錯過了一些東西,因為即使使用該connect函式,結果也是一樣的。這是代碼(簡化):
import Control.Concurrent
import System.IO.Streams
import Data.ByteString
main = do
(sink,_,_,_) <- runInteractiveCommand "mplayer -novideo - cache 5096 -"
mainSink <- lockingOutputStream sink -- main audio stream, goes straight to player
(_,source,_,_) <- runInteractiveCommand "yt-dlp \"https://www.youtube.com/watch?v=uFtfDK39ZhI\" -f bv ba -o -"
loop mainSink source
loop :: OutputStream ByteString -> InputStream ByteString -> IO ()
loop sink src = do
sourceBytes <- peek src
case sourceBytes of
Nothing -> do loop sink src
Just _ -> do
audioBytes <- read src
write audioBytes sink
loop sink src
uj5u.com熱心網友回復:
問題似乎mplayer是在 stdout 和 stderr 上生成其通常的詳細終端輸出,同時yt-dlp在 stderr 上類似地生成輸出。由于您將這些句柄扔掉并且永遠不會耗盡它們,因此最終管道緩沖區會填滿,并且行程會卡住。我不能確切地說為什么一個或兩個行程都會死掉而不是掛起,但這就是正在發生的事情。這是一個簡單的示例,它將不需要的輸出重定向到/dev/null并且似乎可以作業:
import System.IO.Streams
main = do
(sink,_,_,_) <- runInteractiveCommand "mplayer -cache 5096 - 2>/dev/null >&2"
(_,source,_,_) <- runInteractiveCommand "yt-dlp \"https://www.youtube.com/watch?v=uFtfDK39ZhI\" -f bv ba -o - 2>/dev/null"
connect source sink
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/532697.html
