는 배경 내가 웹캠에서 레코드 비디오 클립을 작성한 코드는, 메모리 스트림에 기록UWP - 소켓을 통해 MediaElement로 웹캠 스트리밍 - 깨진 그림?
는, 다음은 비디오로 재 조립에 재생있어 소켓 연결을 통해 데이터를 전송 미디어 요소.
궁극적 인 목표는 서버/카메라가 Windows IOT Raspberry Pi에서 실행되는 아기 모니터 시스템을 만들고 여자 친구와 내가 휴대 전화 또는 노트북에서 볼 수있는 UWP 앱을 만드는 것입니다. 집의 다른 부분에서 카메라를 보는 것 외에도 우리 중 한 명이 집을 비울 때도 로그인 할 수 있으며 PIR 모션 센서와 경고 시스템을 연결하기도하지만 우선 먼저.
시스템 전체가 정상적으로 작동하므로 나에게 받아 들일 수있는 비디오에 5 초의 지연이 있으며 MediaPlaybackList를 사용하면 비디오가 일정한 속도로 끊김없이 원활하게 스트리밍됩니다 (지금 당장 얻을 수 있습니다.) 비디오 간의 전환. MediaPlaybackList는 재생 된 항목을 제거하여 메모리 풋 프린트를 상대적 상수로 유지합니다.
일 문제
비디오가 클라이언트 측에 재생, 그것은 깨진 사진을 자주하지만, 임의 섹션을 가져옵니다. 어쨌든 찾을 수있는 패턴이 아니며 설명 할 수있는 유일한 방법은 그림의 일부가 수평으로 반으로 나뉘며 두 반쪽이 서로 바뀌고 그림의 오른쪽이 표시되는 것입니다. 왼쪽, 그리고 그 반대입니다. 깜박이처럼, 깨진 비트가 몇 초 동안 만 표시됩니다. 다른 하나가 그림의 다른 곳에서 나중에 표시되기 때문입니다. 여기
은 예입니다 : 이제1) 내가, 내가 추출하는 방법을 사용하고 데이터 스트림을 큐에 MediaPlaybackList를 사용하기 시작하기 전에 들어오는 소켓 스트림의 각 비디오를 StorageFile로 로컬 디스크에 저장 한 다음이 StorageFiles를 대기열에 넣고 순서대로 재생 한 다음 나중에 삭제합니다 (소스 코드에이 코드의 버전이 있습니다. 그러나 나는 끔찍하게 비효율적 인 것처럼 StorageFiles를 만들고 파괴한다는 생각을 좋아하지 않습니다.) 그러나이 방법을 사용하여 지금 보았던 깨진 사진을 얻지는 못했습니다 ... 이로 인해 비디오 자체가 훌륭하다고 믿을 수 있습니다. 아마도 다시 함께 놓여지고 스트리밍되는 방식과 관련된 문제 일 것입니다. 미디어 요소?
2) 내 여자 친구의 고양이가 웹캠 (Microsoft Lifecam HD-3000)을 깨닫지 않고 옆으로 쳐다 보았고, 서버를 실행하고 사진이 90도 각도에 있음을 알게되었습니다. 이것에 대한 흥미롭고 당혹스러운 점은 위에서 설명한 것처럼 클라이언트에게 전달 된 그림이 깨지지 않았기 때문입니다. 여기서 볼 수있는 유일한 차이점은 표준 640 x 480이 아닌 480x640 (카메라가 측면에 장착 된 카메라)에서 나온 것입니다. 이것이 의미하는 바는 확실하지 않습니다 ...문제 비디오의 크기/치수와는
- 뭔가에
생각 (그것의 측면에서 잘 연주, 그래서 그와 함께 할 수있는 뭔가입니다)?
- 비트 전송률과 관련이 있습니까?
- 클라이언트에서 바이트가 다시 어셈블되는 방식과 관련이 있습니까?
- 스트림의 인코딩과 관련이 있습니까?
소스
이 여기에 아마 관련이 생각하는 코드 몇 조각을의 전체 솔루션 소스가 여기, GitHub의에서 찾을 수 있습니다 : Video Socket Server .
서버
while (true)
{
try
{
//record a 5 second video to stream
Debug.WriteLine($"Recording started");
var memoryStream = new InMemoryRandomAccessStream();
await _mediaCap.StartRecordToStreamAsync(MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga), memoryStream);
await Task.Delay(TimeSpan.FromSeconds(5));
await _mediaCap.StopRecordAsync();
Debug.WriteLine($"Recording finished, {memoryStream.Size} bytes");
//create a CurrentVideo object to hold stream data and give it a unique id
//which the client app can use to ensure they only request each video once
memoryStream.Seek(0);
CurrentVideo.Id = Guid.NewGuid();
CurrentVideo.Data = new byte[memoryStream.Size];
//read the stream data into the CurrentVideo
await memoryStream.ReadAsync(CurrentVideo.Data.AsBuffer(), (uint)memoryStream.Size, InputStreamOptions.None);
Debug.WriteLine($"Bytes written to stream");
//signal to waiting connections that there's a new video
_signal.Set();
_signal.Reset();
}
catch (Exception ex)
{
Debug.WriteLine($"StartRecording -> {ex.Message}");
break;
}
}
연결
//use the guid to either get the current video, or wait for the
//next new one that's added by the server
Guid guid = Guid.Empty;
Guid.TryParse(command, out guid);
byte[] data = _server.GetCurrentVideoDataAsync(guid);
if (data != null)
await _socket.OutputStream.WriteAsync(data.AsBuffer());
클라이언트 응용 프로그램
byte[] inbuffer = new byte[10000000];
//block on the input stream until we've received the full packet,
//but use the Partial option so that we don't have to fill the entire buffer before we continue.
//this is important, because the idea is to set the buffer big enough to handle any packet we'll receive,
//meaning we'll never fill the entire buffer... and we don't want to block here indefinitely
result = await socket.InputStream.ReadAsync(inbuffer.AsBuffer(), inbuffer.AsBuffer().Capacity, InputStreamOptions.Partial);
//strip off the Guid, leaving just the video data
byte[] guid = result.ToArray().Take(16).ToArray();
byte[] data = result.ToArray().Skip(16).ToArray();
_guid = new Guid(guid);
//wrap the data in a stream, create a MediaSource from it,
//then use that to create a MediaPlackbackItem which gets added
//to the back of the playlist...
var stream = new MemoryStream(data);
var source = MediaSource.CreateFromStream(stream.AsRandomAccessStream(), "video/mp4");
var item = new MediaPlaybackItem(source);
_playlist.Items.Add(item);
로지텍 캠으로 rPI3에이 서버 측을 추가하여 비디오 결함없이 코드를 실행 시켰습니다. 스트리밍 구현에는 좀 더 많은 생각이 필요하다고 생각하지만 저에게는 서버에 문제가있었습니다. 는'_mediaCap.VideoDeviceController.SetMediaStreamPropertiesAsync ( { 프레임 속도 = {분모 = 1, 분자는 = 15}, 높이 480, 폭 = 640, 하위 유형 = "YUY2" } MediaStreamType.VideoRecord, 새로운 VideoEncodingProperties()를) 기다리고 있습니다 ; ' –