2017-08-23 5 views
1

シンプルなビデオエディタがあり、ファイルにビデオを保存すると、ドキュメントhttps://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/process-media-files-in-the-Backgroundの実装がバックグラウンドで実装されます。プログラムは機能しますが、ニュアンスがあります。メインストリームが非アクティブなとき、つまりアプリケーションがタスクバーに最小化されたときや閉じたときにのみ、バックグラウンドでのビデオの保存が行われます。アプリケーションがデプロイされている場合、バックグラウンドのビデオ保存タスクは中断されます。メインアプリケーションがアクティブなときにバックグラウンドタスクを実装する方法を教えてください。ありがとうございました!UWPアプリケーションの背景にビデオファイルを保存する

クラスのバックグラウンドタスク:

using Windows.ApplicationModel.Background; 
using Windows.Storage; 
using Windows.UI.Notifications; 
using Windows.Data.Xml.Dom; 
using Windows.Media.MediaProperties; 
using Windows.Media.Transcoding; 
using System.Threading; 
using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Windows.Media.Editing; 
using Windows.Foundation; 
using Windows.UI.Core; 
using Lumia.Imaging; 
using Lumia.Imaging.Adjustments; 
using Lumia.Imaging.Artistic; 
using System.Collections.Generic; 
using Windows.Foundation.Collections; 
using VideoEffectComponent; 

namespace MediaProcessingBackgroundTask 
{ 
    public sealed class MediaProcessingTask : IBackgroundTask 
    { 
     IBackgroundTaskInstance backgroundTaskInstance; 
     BackgroundTaskDeferral deferral; 
     CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); 
     MediaTranscoder transcoder; 
     MediaComposition composition; 

     MediaClip clip; 
     EffectList effList = new EffectList(); 

     PropertySet configurationPropertySet = new PropertySet(); 
     PropertySet DustPropertySet = new PropertySet(); 
     PropertySet ScretcchPropertySet = new PropertySet(); 
     Windows.Media.Effects.VideoEffectDefinition videoEffect; 

     BrightnessEffect brightnessEff = new BrightnessEffect(); 
     ContrastEffect contrastEff = new ContrastEffect(); 
     HueSaturationEffect saturationEff = new HueSaturationEffect(); 

     public async void Run(IBackgroundTaskInstance taskInstance) 
     { 
      Debug.WriteLine("In background task Run method"); 

      backgroundTaskInstance = taskInstance; 
      taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled); 
      taskInstance.Progress = 0; 

      deferral = taskInstance.GetDeferral(); 
      Debug.WriteLine("Background " + taskInstance.Task.Name + " is called @ " + (DateTime.Now).ToString()); 

      try 
      { 
       await TranscodeFileAsync(); 
       ApplicationData.Current.LocalSettings.Values["TranscodingStatus"] = "Completed Successfully"; 
       SendToastNotification("File transcoding complete."); 

      } 
      catch (Exception e) 
      { 
       Debug.WriteLine("Exception type: {0}", e.ToString()); 
       ApplicationData.Current.LocalSettings.Values["TranscodingStatus"] = "Error ocurred: " + e.ToString(); 
      } 


      deferral.Complete(); 
     } 

     private async Task TranscodeFileAsync() 
     { 
      transcoder = new MediaTranscoder(); 

      try 
      { 
       var settings = ApplicationData.Current.LocalSettings; 

       settings.Values["TranscodingStatus"] = "Started"; 

       var inputFileName = ApplicationData.Current.LocalSettings.Values["InputFileName"] as string; 
       var outputFileName = ApplicationData.Current.LocalSettings.Values["OutputFileName"] as string; 
       var redCurve = ApplicationData.Current.LocalSettings.Values["CurvRed"] as Point[]; 
       var greenCurve = ApplicationData.Current.LocalSettings.Values["CurvGreen"] as Point[]; 
       var blueCurve = ApplicationData.Current.LocalSettings.Values["CurvBlue"] as Point[]; 
       var sat = ApplicationData.Current.LocalSettings.Values["SatVal"]; 
       var brid = ApplicationData.Current.LocalSettings.Values["BridVal"]; 
       var con = ApplicationData.Current.LocalSettings.Values["ContrVal"]; 
       var dust = ApplicationData.Current.LocalSettings.Values["dustCVal"]; 
       var scetch = ApplicationData.Current.LocalSettings.Values["scetchCVal"]; 

       saturationEff.Saturation = (double)sat; 
       brightnessEff.Level = (double)brid; 
       contrastEff.Level = (double)con; 

       CurvesEffect curves = new CurvesEffect(); 
       Curve RedC = new Curve(); 
       Curve GreenC = new Curve(); 
       Curve BlueC = new Curve(); 
       RedC.Points = redCurve; 
       GreenC.Points = greenCurve; 
       BlueC.Points = blueCurve; 
       curves.Blue = BlueC; 
       curves.Green = GreenC; 
       curves.Red = RedC; 

       if (inputFileName == null || outputFileName == null) 
       { 
        return; 
       } 


       var inputFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(inputFileName); 
       var outputFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(outputFileName); 

       composition = await MediaComposition.LoadAsync(inputFile); 

       clip = composition.Clips[0]; 

       effList.Add(saturationEff); 
       effList.Add(brightnessEff); 
       effList.Add(contrastEff); 

       effList.Add(curves); 

       configurationPropertySet.Add(new KeyValuePair<string, object>("Effect", effList)); 

       DustPropertySet = new PropertySet(); 
       DustPropertySet["DustCount"] = dust; 

       ScretcchPropertySet = new PropertySet(); 
       ScretcchPropertySet["ScetchAmount"] = scetch; 

       videoEffect = new Windows.Media.Effects.VideoEffectDefinition("Lumia.Imaging.VideoEffect", configurationPropertySet); 

       clip.VideoEffectDefinitions.Add(new Windows.Media.Effects.VideoEffectDefinition(typeof(Vignet).FullName, VignetPropertySet)); 
       clip.VideoEffectDefinitions.Add(new Windows.Media.Effects.VideoEffectDefinition(typeof(ExampleVideoEffect).FullName, ScretcchPropertySet)); 
       clip.VideoEffectDefinitions.Add(new Windows.Media.Effects.VideoEffectDefinition(typeof(Dust).FullName, DustPropertySet)); 
       clip.VideoEffectDefinitions.Add(videoEffect); 

       MediaEncodingProfile mp = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p); 



       Debug.WriteLine("PrepareFileTranscodeAsync"); 
       settings.Values["TranscodingStatus"] = "Preparing to transcode "; 
       var startTime = TimeSpan.FromMilliseconds(DateTime.Now.Millisecond); 
        Debug.WriteLine("Starting transcoding @" + startTime); 

        var progressT = new Progress<double>(TranscodeProgress); 
        settings.Values["TranscodingStatus"] = "Transcoding "; 
        settings.Values["ProcessingFileName"] = inputFileName; 

       var saveOperation = composition.RenderToFileAsync(outputFile, MediaTrimmingPreference.Precise, mp);// AsTask(cancelTokenSource.Token, progressT); 

       saveOperation.Completed = (info, status) => 
       { 
        SendToastNotification("Video saved."); 
        clip.VideoEffectDefinitions.Clear(); 
        composition = null; 
        deferral.Complete(); 

        if (status != AsyncStatus.Completed) 
        { 
         // ShowErrorMessage("Error saving composition"); 
        } 

       }; 
       await saveOperation.AsTask(cancelTokenSource.Token, progressT); 

       Debug.WriteLine("Source content could not be transcoded."); 

        var endTime = TimeSpan.FromMilliseconds(DateTime.Now.Millisecond); 
        Debug.WriteLine("End time = " + endTime); 

      } 
      catch (Exception e) 
      { 
       Debug.WriteLine("Exception type: {0}", e.ToString()); 
       throw; 
      } 
     } 
     void TranscodeProgress(double percent) 
     { 
      Debug.WriteLine("Transcoding progress: " + percent.ToString().Split('.')[0] + "%"); 
      backgroundTaskInstance.Progress = (uint)percent; 
     } 

     private void SendToastNotification(string toastMessage) 
     { 
      ToastTemplateType toastTemplate = ToastTemplateType.ToastText01; 
      XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate); 
      XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text"); 
      toastTextElements[0].AppendChild(toastXml.CreateTextNode(toastMessage)); 
      ToastNotification toast = new ToastNotification(toastXml); 
      ToastNotificationManager.CreateToastNotifier().Show(toast); 
     } 

     private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) 
     { 

      Debug.WriteLine("Background " + sender.Task.Name + " Cancel Requested..." + reason.ToString()); 
     } 

    } 
} 

登録すると、バックグラウンドでビデオを保存するバックグラウンドタスク

MediaProcessingTrigger mediaProcessingTrigger; 
string backgroundTaskBuilderName = "TranscodingBackgroundTask"; 
BackgroundTaskRegistration taskRegistration; 

private void RegisterBackgroundTask() 
     { 
      // New a MediaProcessingTrigger 
      mediaProcessingTrigger = new MediaProcessingTrigger(); 

      var builder = new BackgroundTaskBuilder(); 

      builder.Name = backgroundTaskBuilderName; 
      builder.TaskEntryPoint = "MediaProcessingBackgroundTask.MediaProcessingTask"; 
      builder.SetTrigger(mediaProcessingTrigger); 

      // unregister old ones 
      foreach (var cur in BackgroundTaskRegistration.AllTasks) 
      { 
       if (cur.Value.Name == backgroundTaskBuilderName) 
       { 
        cur.Value.Unregister(true); 
       } 
      } 

      taskRegistration = builder.Register(); 
      taskRegistration.Progress += new BackgroundTaskProgressEventHandler(OnProgress); 
      taskRegistration.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted); 

      return; 
     } 
     private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args) 
     { 
      string progress = "Progress: " + args.Progress + "%"; 
      Debug.WriteLine(progress); 


      var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       TextSave.Text = progress; 
       ProgressSave.Value = args.Progress; 
      }); 

     } 
     private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args) 
     { 
      Debug.WriteLine(" background task complete"); 
      var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
      { 
       TasckCompleted(); 
      }); 

     } 

private async void LaunchBackgroundTask() 
{ 
    var success = true; 

    if (mediaProcessingTrigger != null) 
    { 
     MediaProcessingTriggerResult activationResult; 
     activationResult = await mediaProcessingTrigger.RequestAsync(); 

     switch (activationResult) 
     { 
      case MediaProcessingTriggerResult.Allowed: 
       // Task starting successfully 
       break; 

      case MediaProcessingTriggerResult.CurrentlyRunning: 
      // Already Triggered 

      case MediaProcessingTriggerResult.DisabledByPolicy: 
      // Disabled by system policy 

      case MediaProcessingTriggerResult.UnknownError: 
       // All other failures 
       success = false; 
       break; 
     } 

     if (!success) 
     { 
      // Unregister the media processing trigger background task 
      taskRegistration.Unregister(true); 
     } 
    } 

} 
+0

私たちがお手伝いする前に、コードをお知らせください。 – Bestter

+0

申し訳ありません、投稿を修正しました –

答えて

0

を起動するには、こと、メインストリームがアクティブでない場合にのみ発生アプリケーションがタスクバーに最小化されるか、閉じられるときです。

上記のコードスニペットでは、バックグラウンドタスクはLaunchBackgroundTask()メソッドによってトリガーされます。バックグラウンドタスクが発生した場合は、このメソッドを呼び出す場所によって、相対コードスニペットを表示しなかったかどうかによって異なります。あなたの説明によると、メインストリームが非アクティブのときにのみバックグラウンドタスクがトリガされ、イベントハンドラ内でこのメソッドを呼び出すと思います。たとえば、EnteredBackgroundイベント内でメソッドを呼び出すと、非アクティブになります。その場合は、button clickイベントで呼び出すなど、要件を満たすためにforegroundを呼び出すメソッドLaunchBackgroundTask()を追加する必要があります。バックグラウンドタスクがトリガーされると

private void btnlaunch_Click(object sender, RoutedEventArgs e) 
{ 
    LaunchBackgroundTask(); 
} 

MediaProcessingTaskは関係なく、アプリはそれが実行してまいりますアクティブまたは非アクティブである、out-of-process background taskではありません。しかし、あなたが私の側でテストすることによって、再配布されたということを意味するなら、これは最初にアプリケーションをアンインストールし、バックグラウンドタスクの登録を解除し、強制的に停止させます。

関連する問題