這是要求不适用CameraCaptureUI等使用系統自帶的 camera UI界面,要求我們自己寫調用攝像頭攝像的方法,現在我把我的程式貼下:
UI界面的程式:
<Page
x:Class="Camera3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Camera3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="btnCamera" Content="調用攝像頭" HorizontalAlignment="Left" Margin="295,83,0,0" VerticalAlignment="Top" Click="btnCamera_Click"/>
<Button x:Name="btnSettings" Content="攝像頭設定" HorizontalAlignment="Left" Margin="482,83,0,0" VerticalAlignment="Top"/>
<Button x:Name="btnVideo" Content="拍攝視訊" HorizontalAlignment="Left" Margin="685,83,0,0" VerticalAlignment="Top" Click="btnVideo_Click"/>
<Button x:Name="btnSave" Content="儲存視訊" HorizontalAlignment="Left" Margin="867,83,0,0" VerticalAlignment="Top" Click="btnSave_Click"/>
<GridView HorizontalAlignment="Left" Margin="246,200,0,0" VerticalAlignment="Top" Width="800" Height="600">
<CaptureElement x:Name="capture1" Height="600" Width="800"/>
</GridView>
</Grid>
</Page>
主程式裡的代碼:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Devices.Enumeration;
using Windows.Media.MediaProperties;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Media;
using Windows.Storage.Streams;
using Windows.Media.Devices;
using System.Threading.Tasks;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace Camera3
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private MediaCapture mediaVideo = null;
private IStorageFile video = null;
private MediaEncodingProfile videoProfile = null;
public MainPage()
{
this.InitializeComponent();
}
public async void btnCamera_Click(object sender, RoutedEventArgs e)
{
try
{
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
if (devices.Count > 0)
{
if (mediaVideo == null)
{
capture1.Source = await Initialize();
await mediaVideo.StartPreviewAsync();
}
}
}
catch (Exception msg)
{
mediaVideo = null;
}
}
public async Task<MediaCapture> Initialize()
{
mediaVideo = new MediaCapture();
await mediaVideo.InitializeAsync();
mediaVideo.VideoDeviceController.PrimaryUse = CaptureUse.Video;
videoProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
return mediaVideo;
}
public async void btnVideo_Click(object sender, RoutedEventArgs e)
{
if (mediaVideo != null)
{
video = await KnownFolders.VideosLibrary.CreateFileAsync("some.mp4", CreationCollisionOption.GenerateUniqueName);
await mediaVideo.StartRecordToStorageFileAsync(videoProfile, video);
}
}
private async void btnSave_Click(object sender, RoutedEventArgs e)
{
if (video != null)
{
FileSavePicker videoPicker = new FileSavePicker();
videoPicker.CommitButtonText = "儲存視訊";
videoPicker.SuggestedFileName = "hello";
videoPicker.FileTypeChoices.Add("視訊", new string[] { ".mp4", ".mpg", ".rmvb", ".mkv" });
videoPicker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
IStorageFile videoFile = await videoPicker.PickSaveFileAsync();
if (videoFile != null)
{
var streamRandom = await video.OpenAsync(FileAccessMode.Read);
IBuffer buffer = RandomAccessStreamToBuffer(streamRandom);
await FileIO.WriteBufferAsync(videoFile, buffer);
}
}
}
//将圖檔寫入到緩沖區
private IBuffer RandomAccessStreamToBuffer(IRandomAccessStream randomstream)
{
Stream stream = WindowsRuntimeStreamExtensions.AsStreamForRead(randomstream.GetInputStreamAt(0));
MemoryStream memoryStream = new MemoryStream();
IBuffer buffer = null;
if (stream != null)
{
byte[] bytes = ConvertStreamTobyte(stream); //将流轉化為位元組型數組
if (bytes != null)
{
var binaryWriter = new BinaryWriter(memoryStream);
binaryWriter.Write(bytes);
}
}
buffer = WindowsRuntimeBufferExtensions.GetWindowsRuntimeBuffer(memoryStream, 0, (int)memoryStream.Length);
return buffer;
}
//将流轉換成二進制
public static byte[] ConvertStreamTobyte(Stream input)
{
byte[] buffer = new byte[1024 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
}
但是這裡出現了一個問題,不知道怎麼解決。
之是以放上來,希望有大牛可以幫我解決一下,看看到底是出現了什麼問題:
這是運作的界面,點選“調用攝像頭”,可以調用攝像頭:
會發現上面的界面已經調用了攝像頭,這一個子產品式沒有什麼問題的。
但是問題出現在下面,下面我點選“拍攝視訊”的按鈕,出現如下異常:
下面我把我捕獲的異常給大家看看:
System.Exception: The specified object or value does not exist.
MediaStreamType
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Camera3.MainPage.<btnVideo_Click>d__9.MoveNext()
上面就是捕獲的異常情況,可以從異常的截圖上發現,出現異常的代碼可能是:
public async void btnVideo_Click(object sender, RoutedEventArgs e)
{
if (mediaVideo != null)
{
video = await KnownFolders.VideosLibrary.CreateFileAsync("some.mp4", CreationCollisionOption.GenerateUniqueName);
<span style="color:#ff0000;">await mediaVideo.StartRecordToStorageFileAsync(videoProfile, video);</span>
}
}
應該就是标記為紅色的那部分代碼,下面我對它進行斷點調試:
上面兩幅斷點調試的圖檔可以看出這
<span style="color:#ff0000;">StartRecordToStorageFileAsync(videoProfile, video)</span>
這個函數的兩個參數均沒有出現問題,參數的傳遞的正确的,現在怎麼會出現這樣的情況。
希望知道的同學可以給我答案,告訴我為什麼,等待您的回複,謝謝同志們。
PS:搞了一下午,終于發現了這個程式的問題,現在把正确的程式源代碼傳上去。
下面是我的程式源代碼,希望打啊多多指正。
http://download.csdn.net/detail/litianpeng1991/7556273