【问题标题】:Haskell broken pipe error when working with streams使用流时出现 Haskell 破管错误
【发布时间】:2022-11-14 02:14:36
【问题描述】:

我正在尝试使用流构建播放器。主要思想是让一个线程运行一个播放器,该播放器读取来自另一个同时下载 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

【问题讨论】:

    标签: multithreading haskell concurrency stream bytestring


    【解决方案1】:

    问题似乎是 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多