0

미디어 플레이어를 사용하여 몇 가지 청각 적 지시를하고 싶습니다. 컴퓨터가 말을하려고 :
는 네 가지의계속하기 전에 MediaPlayer가 완료되기를 기다리는 UWP

한 일 "입력 텍스트 상자와 언론에 이니셜을 입력합니다"

1) 이벤트)
2) 이벤트
3 MediaPlayer.OnMediaPlayerEnded MediaPlayer.OnMediaPlayerFailed 사용자는 작업을 완료하고 MediaPlayer를 여전히 재생되는 동안 프레스 입력
4) 사용자가 아무것도하지 않고 우리가 타임 아웃

MediaPlayer.Play()로 할 경우에도부터는 나 전에 다음 명령어로 제어를 반환 g 녹음을 재생합니다. UI 스레드가 대기해야합니다. 그러나 어떻게? Task.Run/Task.Factory.Run/Task.Factory.RunStart를 사용하여 새 작업을 시작하기로 결정했습니다. 그런 다음 UI 스레드에서 대기 (timeout_interval)하십시오. 그러나 나는 새로운 스레드/태스크에 똑같은 문제를 넘겨 줬다. MediaPlayer.Play()는 사실상 새 작업의 마지막 줄이며 사운드가 끝나기 전에 완료됩니다. OnMediaXxxx가 실행될 때까지 작업을 유지해야합니다. 두 이벤트는 작업을 끝내거나 UI를 취소합니다. 잠깐만() CancellationTokens, CancellationTokenSources 및 다양한 방법으로 기다리고 있습니다.

해결책은 무엇입니까? 내가하려는 일은 효과가없는 것 같아.

+0

을 할 수있는 한 처음에 MediaPlayer가 사운드 재생을 시작한 후 5 초 후에 스레드가 스레드를 기다려서 미디어가 완전히 재생 된 경우이를 활성화합니다. – Pratyay

답변

0

나는 이제 대머리 다. 그러나 성공했다. 녹음이 끝날 때까지 기다리는 일은 모두 끝났다. 그래서 MediaPlay가 끝나기를 기다렸지 만 작동하지 않습니다. 두 번의 연속적인 사운드를 연주하려고 시도 할 경우, 두 번째 사운드가 끝나기 전에 첫 번째 사운드가 끝날 때까지 기다릴 수 없습니다. 하지만이 작품은 ...

static private void PlayAndWait(StorageFile file, double volume) 
    { 
     playCancellationTokenSource = new CancellationTokenSource(); 
     playTask = new Task(() => PlayFile(file, volume), playCancellationTokenSource.Token); 
     playTask.Start(); 
     Task.WaitAny(new Task[] { playTask }, 15_0000); 
    } 

static private void PlayFile(StorageFile file, double volume) 
    { 
     if (MRecording.recordingStatus != RecordingStatus.Idle) 
      throw new LogicException("PlayStorageFile: RecordingStatus not Idle"); 
     FileNowPlaying = file; 
     var mediaPlayer = new MediaPlayer { AutoPlay = false, AudioCategory = MediaPlayerAudioCategory.Media }; 
     mediaPlayer.MediaFailed += OnMediaPlayerFailed; // one of these two should release the mutex 
     mediaPlayer.MediaEnded += OnMediaPlayerEnded; 
     mediaPlayer.AudioCategory = Windows.Media.Playback.MediaPlayerAudioCategory.Media; 

     MediaSource mediaSource = MediaSource.CreateFromStorageFile(file); 
     var mediaPlaybackItem = new MediaPlaybackItem(mediaSource); 
     mediaPlayer.Source = mediaPlaybackItem; 
     mediaPlayer.Volume = volume; 
     MRecording.recordingStatus = RecordingStatus.Playing; 
     try 
     { 
      FileNowPlaying = file; 
      mediaPlayer.Play(); 
      playTask.Wait(playCancellationTokenSource.Token); 
     } 
     catch (OperationCanceledException) 
     { } 
     catch (Exception e) 
     { 
      throw new LogicException("PlayFile", e); 
     } 
     FileNowPlaying = null; 
     recordingStatus = RecordingStatus.Idle; 
    } 
    static void OnMediaPlayerFailed(object sender, MediaPlayerFailedEventArgs e) => PlayCleanUp(); 
static void OnMediaPlayerEnded(object sender, MediaPlayerFailedEventArgs e) => PlayCleanUp(); 
static void PlayCleanUp() 
    { 
     recordingStatus = RecordingStatus.Idle; 
     if (playTask == null) 
      throw new LogicException("playTask null"); 

     string msg = string.Empty; 
     AggregateException exceptions = playTask.Exception; 
     if (exceptions != null) 
      foreach (Exception e in exceptions.InnerExceptions) 
      { 
       msg += e.Message + Statics.CRLF2; 
       throw new LogicException("PlayCleanUp exception: " + msg); 
      } 
     playCancellationTokenSource.Cancel(); 
    } 

그래서 지금은 내가 그 일을 여러 가지 방법이 그 중 하나가 당신이 텍스트 상자를 비활성화 할 수 있다는 것입니다 ..이 확신 다음

PlayAndWait(StorageFile1, volume:1.0); 
PlayAndWait(StorageFile2, volume:0.5); 
PlayAndWait(StorageFile3, volume:0.7);