【问题标题】:Stream video from local video file VB.Net从本地视频文件 VB.Net 流式传输视频
【发布时间】:2017-01-27 01:47:09
【问题描述】:

我正在制作一个远程助手程序,它应该将屏幕截图发送到我的服务器。我使用 TCP。问题是客户端将高速发送数据包,如果我的服务器速度很慢,我将无法处理即将到来的图像,并且会出现内存溢出异常(因为一张图像占用内存高达 30 MB) .我想出了一个主意:在磁盘上缓冲 avi 文件中的图像(就像许多视频音频流应用程序所做的那样,比如 MJPEG 模式)。我为此找到了完美的库:DirectShow and Video from AForge。 基本上,我在读取它的同时写入一个 avi 文件(以 FIFO 样式)。 这是流式传输的测试项目(我将几张图片写入 avi 并尝试阅读):

Public Class Form1
    Dim thr As New Thread(AddressOf write)
    Dim videowriter As New VideoFileWriter
    Dim WithEvents vid As New AVIReader
    Dim WithEvents vidd As DirectShow.FileVideoSource
    Dim cc As Long, used As Boolean
    Dim aa As FilterInfoCollection, bb As New VideoCaptureDevice

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If File.Exists(Application.StartupPath & "/video/stream.avi") Then File.Delete(Application.StartupPath & "/video/stream.avi")
        thr.Start()
        Thread.Sleep(1000) 'wait so that the avi contains some frames

        vidd = New DirectShow.FileVideoSource(Application.StartupPath & "/video/stream.avi")
        vidd.Start()
    End Sub

    Sub a(sender As Object, args As NewFrameEventArgs) Handles vidd.NewFrame
        draw(args.Frame.Clone)
        Thread.Sleep(100) 'wait again
    End Sub


    Sub draw(ByRef pic As Bitmap)
        If PictureBox1.Image IsNot Nothing Then
            PictureBox1.Image.Dispose()
            PictureBox1.Image = Nothing
        End If

        PictureBox1.Image = pic
    End Sub

    Sub write()
        Dim count As Integer = 0
        Dim crop_bit As New Bitmap(320, 240), bit As Bitmap
        Dim g As Graphics = Graphics.FromImage(crop_bit)

        videowriter.Open(Application.StartupPath & "/video/stream.avi", 320, 240, 100, VideoCodec.MPEG4)

        For Each fil As String In Directory.GetFiles(Application.StartupPath & "/pictures")
            count += 1
            Debug.Print(count)

            bit = Image.FromFile(fil)

            g.DrawImage(bit, 0, 0, 320, 240)

            videowriter.WriteVideoFrame(crop_bit)
            bit.Dispose()
        Next
        'STOP..here
        videowriter.Close()
    End Sub
End Class 

但它不起作用。没有错误。它创建文件..视频一切,但它在图片框上不显示任何图像。似乎当它写入 avi 时,它以 WriteOnly 的形式打开并且不允许读取(也许?)。有什么办法吗?我听说过队列,但它仍然存储在内存中......它必须在磁盘上。是否可以选择制作我自己的类似 MJPEG 的文件(将每个图像存储在此文件中的某些分隔符/标题中)?

【问题讨论】:

    标签: vb.net video


    【解决方案1】:

    30Mb 对于屏幕截图来说是巨大的。

    您可能会考虑找出它为什么这么大,然后解决问题或压缩图像。任何拥有正常家庭互联网连接甚至普通企业连接的人都不太可能流式传输 30Mb 帧。

    如果您的服务器跟不上,则流式传输屏幕截图将无济于事,事实上,由于增加了开销,它会使其变慢。

    要解决您的问题,当您的服务器或网络连接太慢时,您需要丢帧或显着减小图像大小。流式传输无济于事。

    值得一提的是,实际的流媒体服务器以多种分辨率和帧速率对媒体进行转码,正是出于这个原因。有光纤互联网连接的人可能能够流式传输完整的 1080P 或更好的视频,而使用 2g 手机的人可能需要缩减到(180x320?)和几帧/秒,但是如果你这样做可能是不可接受的'正在处理需要可读的屏幕截图。

    【讨论】:

    • 这正是我的想法。但我查看了我的所有代码(来自 tcp 类)。似乎图片框可以做到这一点。我添加了带有picturebox1.image.dispose 的部分,但是GC仍然被连续调用,因为它使用了太多的内存(我使用Visual Studio 2015,我可以看到它何时被调用)。我想我在某个地方做重复。我会进一步搜索。
    • 但这不是真正的问题。问题是读/写。现在我正在创建自己的类似 mjpeg 的格式。这将花费我一天的时间。我已经创建了 2 个其他类来满足我的需要。
    • 问题不在于读写。问题是您试图将 2 吨肥料放入 1 吨皮卡车中。你只是没有能力做到这一点。但是,既然您提到您正在使用 BMP,我可以告诉您,您找不到比这更有效的处理图像的方法了。我要做的第一件事是找到更好的格式。也许是 PNG。 paulbourke.net/dataformats/bitmaps
    • "问题在于读/写。现在我正在创建自己的类似 mjpeg 的格式。这将花费我一天的时间。"这将需要比一天更长的时间。
    猜你喜欢
    • 2010-10-25
    • 2016-01-07
    • 2016-07-28
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多