C# стрим и кеширование видео

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ImDoode, 7 Mar 2013.

  1. ImDoode

    ImDoode New Member

    Joined:
    24 Mar 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Хорошего настроения каждому зашедшему.
    Не могу справиться с проблемой.
    Дано: приложение на с#, удаленный сервер с видео, приложение стримит видео с удаленного сервера.

    Нужно сделать: сохранение стрима на компьютер, чтобы каждое просмотренное видео можно было отыграть в оффлайне.

    Идея: сорц видеокомпонента посылает запрос не на сервер, а на "локальную прокси" (класс listener), этот класс заменяет Host в хедере с 127.0.0.1:1489 на айпишник удаленного сервера, начинает стримить с сервера в видеокомпонент, попутно записывая получаемую информацию (видео) на диск.

    Что есть: собственно, готов сам стрим без использования прокси, класс прокси (подключение к нему проходит успешно).

    Что не получается сделать: наадить стрим в приложение через класс listener.

    Не знаю, как послать запрос на получение данных из прокси на сервер.

    Класс listener (прокси):

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    
    
    using System.IO;
    using System.Threading;
    using System.Text.RegularExpressions;
    
    namespace Teacher
    {
        public class Listener
        {
    
            public TcpListener _listener;
    
            private void HandleClientComm(object client)
            {
                TcpClient tcpClient = (TcpClient)client;
                NetworkStream clientStream = tcpClient.GetStream();
    
                byte[] message = new byte[4096];
                int bytesRead;
    
                while (true)
                {
                    bytesRead = 0;
    
                    try
                    {
                        //blocks until a client sends a message
                        bytesRead = clientStream.Read(message, 0, 4096);
                    }
                    catch
                    {
                        //a socket error has occured
                        break;
                    }
    
                    if (bytesRead == 0)
                    {
                        //the client has disconnected from the server
                        break;
                    }
    
                    //message has successfully been received
                    ASCIIEncoding encoder = new ASCIIEncoding();
                    string resp = encoder.GetString(message, 0, bytesRead);
                    System.Diagnostics.Debug.WriteLine(resp);
    
                    //вот где-то тут нужно формировать и посылать хедер, но я не знаю, как
                    int indx = resp.IndexOf("Host");
                    string pattern = @"\b(\w+)\s\1\b";
                                    
                    Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
                    
                    var address = Dns.GetHostAddresses("hanker.ru")[0];
    
                    string newresp = rgx.Replace(resp, "Host: 127.0.0.1:1488", "Host: " + address + ":1488");
    
    
    
    
                }
    
                tcpClient.Close();
            }
    
            public Listener()
            {
                new Thread(Start) { IsBackground = true }.Start();
    
            }
    
            private void Start()
            {
                _listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1488);
                //catch the MediaPlayer requests here 
                _listener.Start();
                while (true)
                {
                    //blocks until a client has connected to the server
                    TcpClient client = _listener.AcceptTcpClient();
                    // here was first an message that send hello client
                    //
                    ///////////////////////////////////////////////////
                    //create a thread to handle communication
                    //with connected client
                    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                    clientThread.Start(client);
                }
            }
    
    
            //do streaming and caching here
    
            private int StreamAndSave(Stream outputNetStream, Stream responceStream, Stream fileStream, long fileSize)
            {
                int bytesRead = 0;
                byte[] buffer = new byte[4096];
                while (fileSize > 0)
                {
                    int readBytes = responceStream.Read(buffer, 0, buffer.Length);
                    if (readBytes > 0)
                    {
                        try
                        {
                            //write bytes to response and send it to MediaPlayer
                            outputNetStream.Write(buffer, 0, readBytes);
                            //save to the file system
                            fileStream.Write(buffer, 0, readBytes);
                            bytesRead += readBytes;
                        }
                        catch (Exception e)
                        {
                            break;
                        }
                    }
                    else break;
                    fileSize -= readBytes;
                }
                return bytesRead;
            }
        }
    }
    
    Код обращения к прокси:

    Code:
    private void btnPlayVideo_Click(object sender, RoutedEventArgs e)
            {
                var w = SecondWindow.Instance;
                Listener SnS = new Listener(); //http://serverwithvideo.ru/files/{0}/{1}/video/{2}/{3}.mp4
                var uri = new Uri(string.Format(@"http://127.0.0.1:1488/files/{0}/{1}/video/{2}/{3}.mp4", w.DBroot.ShortName, w.CurrentFrame.Episode.Part.SelfIndex + 1, w.CurrentFrame.Episode.SelfIndex + 1, w.CurrentFrame.Scene.SelfIndex + 1));
                if (videoPlayer.Source != uri)
                    videoPlayer.Source = uri;
                if (State == Teacher.VideoState.Playing)
                {
                    Pause();
                }
                else
                {
                    Play();
                }
            }
    
    Помогите разобраться!