我正在尝试使用AudioVideoCaptureDevice在Windows Phone上捕获视频,但是当我尝试设置captureSource时,我收到一条错误消息,指出“由于对象的状态,操作无效”。你能告诉我在下面的代码中做什么吗?
代码段:
// Viewfinder for capturing video.
private VideoBrush videoRecorderBrush;
// Source and device for capturing video.
private CaptureSource _cs;
private VideoCaptureDevice _cd;
private AudioVideoCaptureDevice vcDevice;
double w, h;
// File details for storing the recording.
private IsolatedStorageFileStream isoVideoFile;
private FileSink fileSink;
private string isoVideoFileName = "iClips_Video.mp4";
private StorageFile sfVideoFile;
// For managing button and application state.
private enum ButtonState { Initialized, Stopped, Ready, Recording, Playback, Paused, NoChange, CameraNotSupported };
private ButtonState currentAppState;
// Constructor
public MainPage()
{
try
{
InitializeComponent();
//setup recording
// Prepare ApplicationBar and buttons.
PhoneAppBar = (ApplicationBar)ApplicationBar;
PhoneAppBar.IsVisible = true;
StartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
StopPlaybackRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
StartPlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[2]);
PausePlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[3]);
SetScreenResolution();
//initialize the camera task
cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
if (isFilePresent("username") && isFilePresent("Password"))
{
if (isFilePresent("IsProfilePhotoOnServer"))
{
connectToSocket();
}
else
{
SignUpProfilePhoto();
}
}
else
{
SignIn();
}
}
catch (Exception ex)
{
this.Dispatcher.BeginInvoke(delegate()
{
MessageBox.Show("Constructor Error:\n"+ ex.Message);
});
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Initialize the video recorder.
InitializeVideoRecorder();
//prepare shutter hot keys
CameraButtons.ShutterKeyHalfPressed += OnButtonHalfPress;
CameraButtons.ShutterKeyPressed += OnButtonFullPress;
CameraButtons.ShutterKeyReleased += OnButtonRelease;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// Dispose of camera and media objects.
DisposeVideoPlayer();
DisposeVideoRecorder();
base.OnNavigatedFrom(e);
CameraButtons.ShutterKeyHalfPressed -= OnButtonHalfPress;
CameraButtons.ShutterKeyPressed -= OnButtonFullPress;
CameraButtons.ShutterKeyReleased -= OnButtonRelease;
}
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
if (vcDevice != null)
{
if (e.Orientation == PageOrientation.LandscapeLeft)
{
txtDebug.Text = "LandscapeLeft";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate sign in link
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
}
if (e.Orientation == PageOrientation.PortraitUp)
{
txtDebug.Text = "PortraitUp";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 0;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate sign in link
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 0;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
}
if (e.Orientation == PageOrientation.LandscapeRight)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "LandscapeRight";
// Rotate for LandscapeRight orientation.
//videoRecorderBrush.RelativeTransform =
//new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 180 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate MyGrid
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
});
}
if (e.Orientation == PageOrientation.PortraitDown)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "PortraitDown";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 270 };
});
}
}
}
// Hardware shutter button Hot-Actions.
private void OnButtonHalfPress(object sender, EventArgs e)
{
//toggle between video- play and pause
try
{
this.Dispatcher.BeginInvoke(delegate()
{
if (StartPlayback.IsEnabled)
{
PlayVideo();
}
if (PausePlayback.IsEnabled)
{
PauseVideo();
}
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
private void OnButtonFullPress(object sender, EventArgs e)
{
// Focus when a capture is not in progress.
try
{
this.Dispatcher.BeginInvoke(delegate()
{
if (vcDevice != null)
{
//stopVideoPlayer if it's playing back
if (currentAppState == ButtonState.Playback || currentAppState == ButtonState.Paused)
{
DisposeVideoPlayer();
StartVideoPreview();
}
if (StartRecording.IsEnabled)
{
StartVideoRecording();
}
else
{
StopVideoRecording();
}
}
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
private void OnButtonRelease(object sender, EventArgs e)
{
try
{
this.Dispatcher.BeginInvoke(delegate()
{
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
// Update the buttons and text on the UI thread based on app state.
private void UpdateUI(ButtonState currentButtonState, string statusMessage)
{
// Run code on the UI thread.
Dispatcher.BeginInvoke(delegate
{
switch (currentButtonState)
{
// When the camera is not supported by the phone.
case ButtonState.CameraNotSupported:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// First launch of the application, so no video is available.
case ButtonState.Initialized:
StartRecording.IsEnabled = true;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// Ready to record, so video is available for viewing.
case ButtonState.Ready:
StartRecording.IsEnabled = true;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = true;
PausePlayback.IsEnabled = false;
break;
// Video recording is in progress.
case ButtonState.Recording:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// Video playback is in progress.
case ButtonState.Playback:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = true;
break;
// Video playback has been paused.
case ButtonState.Paused:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = true;
PausePlayback.IsEnabled = false;
break;
default:
break;
}
// Display a message.
txtDebug.Text = statusMessage;
// Note the current application state.
currentAppState = currentButtonState;
});
}
public async void InitializeVideoRecorder()
{
try
{
if (_cs == null)
{
_cs = new CaptureSource();
fileSink = new FileSink();
_cd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
CameraSensorLocation location = CameraSensorLocation.Back;
var captureResolutions =
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(location);
vcDevice = await AudioVideoCaptureDevice.OpenAsync(location, captureResolutions[0]);
vcDevice.RecordingFailed += OnCaptureFailed;
vcDevice.VideoEncodingFormat = CameraCaptureVideoFormat.H264;
vcDevice.AudioEncodingFormat = CameraCaptureAudioFormat.Aac;
// Initialize the camera if it exists on the phone.
if (vcDevice != null)
{
//initialize fileSink
await InitializeFileSink();
// Create the VideoBrush for the viewfinder.
videoRecorderBrush = new VideoBrush();
videoRecorderBrush.SetSource(_cs);
// Display the viewfinder image on the rectangle.
viewfinderRectangle.Fill = videoRecorderBrush;
_cs.Start();
// Set the button state and the message.
UpdateUI(ButtonState.Initialized, "Tap record to start recording...");
}
else
{
// Disable buttons when the camera is not supported by the phone.
UpdateUI(ButtonState.CameraNotSupported, "A camera is not supported on this phone.");
}
}
}
catch(Exception ex)
{
MessageBox.Show("InitializeVideoRecorder Error:\n" + ex.Message);
}
}
public async Task InitializeFileSink()
{
StorageFolder isoStore = ApplicationData.Current.LocalFolder;
sfVideoFile = await isoStore.CreateFileAsync(
isoVideoFileName,
CreationCollisionOption.ReplaceExisting);
}
private void OnCaptureFailed(AudioVideoCaptureDevice sender, CaptureFailedEventArgs args)
{
MessageBox.Show(args.ToString());
}
private void OnCaptureSourceFailed(object sender, ExceptionRoutedEventArgs e)
{
MessageBox.Show(e.ErrorException.Message.ToString());
}
// Set the recording state: display the video on the viewfinder.
private void StartVideoPreview()
{
try
{
// Display the video on the viewfinder.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Stopped)
{
// Add captureSource to videoBrush.
videoRecorderBrush.SetSource(_cs);
// Add videoBrush to the visual tree.
viewfinderRectangle.Fill = videoRecorderBrush;
_cs.Start();
// Set the button states and the message.
UpdateUI(ButtonState.Ready, "Ready to record.");
//Create optional Resolutions
}
}
// If preview fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Set recording state: start recording.
private void StartVideoRecording()
{
try
{
// Connect fileSink to captureSource.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
// Connect the input and output of fileSink.
fileSink.CaptureSource = _cs;
fileSink.IsolatedStorageFileName = isoVideoFileName;
}
// Begin recording.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Stopped)
{
_cs.Start();
}
// Set the button states and the message.
UpdateUI(ButtonState.Recording, "Recording...");
StartTimer();
}
// If recording fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Set the recording state: stop recording.
private void StopVideoRecording()
{
try
{
// Stop recording.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
// Disconnect fileSink.
fileSink.CaptureSource = null;
fileSink.IsolatedStorageFileName = null;
// Set the button states and the message.
UpdateUI(ButtonState.Stopped, "Preparing viewfinder...");
StopTimer();
StartVideoPreview();
}
}
// If stop fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Start the video recording.
private void StartRecording_Click(object sender, EventArgs e)
{
// Avoid duplicate taps.
StartRecording.IsEnabled = false;
StartVideoRecording();
}
private void DisposeVideoRecorder()
{
if (_cs != null)
{
// Stop captureSource if it is running.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
}
// Remove the event handler for captureSource.
_cs.CaptureFailed -= OnCaptureFailed;
// Remove the video recording objects.
_cs = null;
vcDevice = null;
fileSink = null;
videoRecorderBrush = null;
}
}
private void OnCaptureFailed(object sender, ExceptionRoutedEventArgs e)
{
throw new NotImplementedException();
}
//STOP WATCH
private void StartTimer()
{
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
startTime = System.DateTime.Now;
}
private void StopTimer()
{
dispatcherTimer.Stop();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
System.DateTime now = System.DateTime.Now;
txtRecTime.Text = now.Subtract(startTime).ToString();
}
在initializeVideoRecorder()中抛出错误。
答案 0 :(得分:0)
似乎你的代码太长了,无法分析为评论中提到的@john。但是,既然您已建议在此处发布一些有用的链接,请执行以下操作:在msdn中执行这些步骤后,可以毫无问题地工作,因为我已尝试过一次。
如果你真的需要一个样本开始,那么msdn就有一个样本。希望您能最大化实用程序。
答案 1 :(得分:0)
我发现我必须将捕获设备传递给videobrush以使其正常工作。我仍然不确定在使用AudioVideoCaptureDevice捕获时我应该使用CaptureSource。无论如何这里是解决方案代码:
// Create the VideoBrush for the viewfinder.
videoRecorderBrush = new VideoBrush();
videoRecorderBrush.SetSource(vcDevice); //substitute vcDevice with captureSource - vcDevice is the reference of AudioVideoCaptureDevice
// Display the viewfinder image on the rectangle.
viewfinderRectangle.Fill = videoRecorderBrush;