Операция не разрешена Windows Phone 8 устройства захвата

У меня есть приложение для Windows Phone 8, которое я обновляю, чтобы добавить возможности загрузки / выгрузки видео. У меня проблема с той частью, где я размещаю поток видеофайлов на IsolatedStorageFileStream, который бросает необработанные исключения.

Ранее я использовал простой API для видеосъемки (VideoCaptureDevice в сочетании с использованием FileSink), и не было никаких проблем при сохранении файла в изолированное хранилище. Это было хорошо, но наше приложение нуждается в большем контроле над сжатием видео, поэтому я переключился, используя передовой API камеры для захвата видео, AudioVideoCaptureDevice, который использует IRandomAccessStream в качестве потоковой поддержки файла.

У меня не было проблем с получением самого видео с помощью расширенных API, ТОЛЬКО проблема заключается в том, когда IsolatedStorageFileStream used генерирует необработанное исключение, которое указывает на объект исключения:

System.IO.IsolatedStorageException: Operation not permitted on IsolatedStorageFileStream.

Исключение выдается каждый раз, когда я открываю / создаю IsolatedStorageFileStream файл, который уже использовался ранее. Я попробовал все от закрытия IsolatedStorageFileStream, утилизировать его и даже установить объект на ноль.

Это фрагмент кода для моих реализаций видеосъемки, а также код для получения IsolatedStorageFileStream получить экземпляр IRandomAccessStream для использования с API видео (все в одном классе) (проблемный код здесь в методе StartOptimizedRecord(), который при вызове в другой раз, то есть, когда пользователь пытается перезаписать видео, вызывает необработанное исключение System.IO.IsolatedStorageException и / или System.ObjectDisposedException:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Windows.Threading;
using System.IO;
using System.Globalization;
using Policelink.Models;
using System.Windows.Media.Imaging;
using Windows.Phone.Media.Capture;
using Microsoft.Devices;
using Windows.Storage.Streams;
using Windows.Storage;

namespace Policelink.Views
{
    public partial class VideoCapturePage : PhoneApplicationPage
    {
        private VideoBrush videoBrush;
        private IsolatedStorageFileStream isoVidFile;
        private EyeWitnessReportVideo reportVideo;

        //static readonly string videoFileName = "video1.mp4";
        string videoFileName = "";
        bool recording = false;
        TimeSpan timeElapsed;

        BitmapImage pauseImage;
        BitmapImage playImage;

        BitmapImage thumbnailImage;
        MemoryStream thumbnailStream;

        private const int maxLength = 60;

        bool playing = false;

        DispatcherTimer timer = new DispatcherTimer();
        public VideoCapturePage()
        {
            InitializeComponent();
            timer.Tick += timer_Tick;
            timer.Interval = TimeSpan.FromSeconds(1);
            pauseImage = new BitmapImage();
            //pauseImage = new BitmapImage(new Uri("Assets/media-pause.png",UriKind.RelativeOrAbsolute));
            var pauseStream = Application.GetResourceStream(new Uri("Assets/media-pause.png", UriKind.RelativeOrAbsolute)).Stream;
            pauseImage.SetSource(pauseStream);
            playImage = (BitmapImage) PlayPauseButtonImage.Source;
            reportVideo = new EyeWitnessReportVideo();
            GenerateCurrentVideoFileName();
            CameraButtons.ShutterKeyPressed += CameraButtons_ShutterKeyPressed;
        }

        void CameraButtons_ShutterKeyPressed(object sender, EventArgs e)
        {
            ToggleRecordVideo();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            timeElapsed = timeElapsed.Add(TimeSpan.FromSeconds(1));
            TimeText.Text = timeElapsed.ToString(@"mm\:ss");
            if (timeElapsed.TotalSeconds >= maxLength)
            {
                timer.Stop();
                StopOptimizedRecord();
                recording = false;
                ToggleAcceptButton(true);
            }
        }

        void ResetElapsed()
        {
            timeElapsed = TimeSpan.FromSeconds(0);
        }

        void StartTimer()
        {
            timer.Start();
        }

        void StopTimer()
        {
            timer.Stop();
        }

        private const string VideoFormatExt = ".mp4";

        void GenerateCurrentVideoFileName()
        {
            string timestamp = DateTime.Now.ToBinary().ToString();
            videoFileName = timestamp + VideoFormatExt;
            Debug.WriteLine("Timestamp for currentvideo filename: " + timestamp);
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            InitializeOptimizedCamera();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            UninitializeOptimizedCamera();
        }


        AudioVideoCaptureDevice vidCaptureDevice;

        async void InitializeOptimizedCamera()
        {
            if (AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back))
            {
                var res = GetLowestVideoResolution();
                var resPrev = GetLowestPreviewResolution();
                vidCaptureDevice = await AudioVideoCaptureDevice.OpenAsync(CameraSensorLocation.Back, res);
                vidCaptureDevice.AudioEncodingFormat = CameraCaptureAudioFormat.Aac;
                vidCaptureDevice.VideoEncodingFormat = CameraCaptureVideoFormat.H264;
                await vidCaptureDevice.SetPreviewResolutionAsync(resPrev);
                vidCaptureDevice.RecordingFailed += openedCam_RecordingFailed;
                vidCaptureDevice.PreviewFrameAvailable += vidCaptureDevice_PreviewFrameAvailable;
                SetCaptureDeviceProperties();

                videoBrush = new VideoBrush();
                videoBrush.SetSource(vidCaptureDevice);
                RecordViewFinder.Fill = videoBrush;

            }
        }

        void vidCaptureDevice_PreviewFrameAvailable(ICameraCaptureDevice sender, object args)
        {

            //throw new NotImplementedException();
        }

        IRandomAccessStream videoStream;

        async void StartOptimizedRecord()
        {
            if (vidCaptureDevice != null)
            {
                OpenIsoVideoFile();
                await vidCaptureDevice.StartRecordingToStreamAsync(videoStream);

                ResetElapsed();
                StartTimer();

                //thumbnailStream = new MemoryStream();
            }
        }

        void GetStreamFromIsolatedStorageVideoFile()
        {
            using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                isoVidFile = isoFile.OpenFile(videoFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                videoStream = (IRandomAccessStream)isoVidFile.AsOutputStream();
            }
        }

        // calling this method also, but unhandled exception still continues..
        void ResetIsoVideoStreamFile()
        {
            if (videoStream != null)
            {
                videoStream.Dispose();
                videoStream = null;
            }
            if (isoVidFile != null)
            {
                isoVidFile.Dispose();
                isoVidFile.Close();
                //isoVidFile = null;
            }
        }

        void OpenIsoVideoFile()
        {
            using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isoFile.FileExists(videoFileName))
                {
                    isoFile.DeleteFile(videoFileName);
                }
                // THIS is where the exception starts, on the call of new IsolatedStorageFileStream, when OpenIsoVideoFile() is being called again after first call..
                isoVidFile = new IsolatedStorageFileStream(videoFileName, FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite, isoFile);
                // Codes below commented doesn't work either, throws the same exception as above...
                //ResetIsoVideoStreamFile();
                //isoVidFile = isoFile.CreateFile(videoFileName);
                //isoVidFile = isoFile.OpenFile(videoFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                videoStream = (IRandomAccessStream)isoVidFile.AsOutputStream();
            }
        }
        // attempts to fix the error of the unhandled exception, but this one to no avail...
        void CloseIsoVideoFile()
        {
            if (videoStream != null)
            {
                videoStream.Dispose();
            }
            if (isoVidFile != null)
            {
                isoVidFile.Dispose();
                isoVidFile.Close();
            }
        }

        async void StopOptimizedRecord()
        {
            if (vidCaptureDevice != null)
            {
                StopTimer();
                await vidCaptureDevice.StopRecordingAsync();
                LoadVideoPlayerFromIsoFile();
                TogglePlayPauseButtonVisibility(true);
                TogglePlayPauseButton(true);
            }
        }

        void SetCaptureDeviceProperties()
        {
            if (vidCaptureDevice != null)
            {
                var profile = KnownCameraAudioVideoProperties.H264EncodingProfile;
                var level = KnownCameraAudioVideoProperties.H264EncodingLevel;
                var profileProp = H264EncoderProfile.Extended;
                var levelProp = H264EncoderLevel.Level1_3;
                vidCaptureDevice.SetProperty(profile, profileProp);
                vidCaptureDevice.SetProperty(level, levelProp);
            }
        }

        void UninitializeOptimizedCamera()
        {
            if (vidCaptureDevice != null)
            {

                vidCaptureDevice.PreviewFrameAvailable -= vidCaptureDevice_PreviewFrameAvailable;
                vidCaptureDevice.RecordingFailed -= openedCam_RecordingFailed;

                vidCaptureDevice.Dispose();

                vidCaptureDevice = null;
                videoBrush = null;

                recording = false;

            }
        }

        void openedCam_RecordingFailed(AudioVideoCaptureDevice sender, CaptureFailedEventArgs args)
        {

        }

        Windows.Foundation.Size GetLowestVideoResolution()
        {
            var camOkay = AudioVideoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back);
            var sorted = camOkay.OrderBy(s => s.Width);
            var lowest = sorted.First();
            return lowest;
        }

        Windows.Foundation.Size GetLowestPreviewResolution()
        {
            var res = AudioVideoCaptureDevice.GetAvailablePreviewResolutions(CameraSensorLocation.Back);
            var sorted = res.OrderBy(s => s.Width);
            return sorted.First();
        }

        void TogglePlayPauseButton(bool play)
        {
            playing = play;
            PlayPauseButtonImage.Source = playing ? playImage : pauseImage;
        }

        void TogglePlayPauseButtonVisibility(bool visible)
        {
            PlayPauseButton.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
        }

        void LoadVideoPlayerFromIsoFile()
        {
            if (isoVidFile != null)
            {
                this.RecorderMediaElement.SetSource(isoVidFile);

            }
        }

        private void RecordClick(object sender, EventArgs e)
        {
            ToggleRecordVideo();
        }

        void ToggleRecordVideo()
        {
            if (!recording)
            {
                ToggleRecordViewFinderAndPreviewDisplay(true);
                TogglePlayPauseButtonVisibility(false);
                ToggleAcceptButton(false);
                StartOptimizedRecord();
                recording = true;
            }
            else
            {
                StopOptimizedRecord();
                recording = false;
                ToggleAcceptButton(true);
                ToggleRecordViewFinderAndPreviewDisplay(false);
                TogglePlayPauseButtonVisibility(true);
                TogglePlayPauseButton(true);
            }
        }
        private void RecorderMediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            this.TogglePlayPauseButton(true);
        }

        private void SaveToGlobal()
        {
            reportVideo.VideoLocalUrl = videoFileName;
            //GetThumbnailFromVideoPreview();
            App.ArgHelper.CurrentTakenVideo = reportVideo;
        }

        private void GetThumbnailFromVideoPreview()
        {
            if (thumbnailStream == null)
            {
                var wb = new WriteableBitmap(this.RecorderMediaElement, null);
                wb.SaveJpeg(thumbnailStream, (int)currentFormat.PixelWidth, (int)currentFormat.PixelHeight, 0, 60);
            }
            reportVideo.Thumbnail = thumbnailStream;
        }

        private void PlayClick(object sender, EventArgs e)
        {
            if (videoStream != null)
            {
                this.RecorderMediaElement.Play();
            }
        }

        private void PlayPauseButton_Click(object sender, RoutedEventArgs e)
        {
            if (playing)
            {
                if (videoStream != null)
                {
                    this.RecorderMediaElement.Play();
                }
            }
            else
            {
                RecorderMediaElement.Pause();
            }
            TogglePlayPauseButton(!playing);
        }

        private void ToggleAcceptButton(bool toggle)
        {
            var acceptBtn = this.ApplicationBar.Buttons[1] as ApplicationBarIconButton;
            acceptBtn.IsEnabled = toggle;
        }

        private void AcceptClick(object sender, EventArgs e)
        {
            SaveToGlobal();
            this.NavigationService.GoBack();
        }

        void ToggleRecordViewFinderAndPreviewDisplay(bool toggleRecordViewFinder)
        {
            this.RecorderMediaElement.Visibility = !toggleRecordViewFinder ? Visibility.Visible : Visibility.Collapsed;
            this.RecordViewFinder.Visibility = toggleRecordViewFinder ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}

0 ответов

Другие вопросы по тегам