diff --git a/src/avfoundation.cs b/src/avfoundation.cs index 072eac814b82..4a272feab841 100644 --- a/src/avfoundation.cs +++ b/src/avfoundation.cs @@ -5674,22 +5674,67 @@ interface AVAsset : NSCopying { [Export ("loadMetadataForFormat:completionHandler:")] void LoadMetadata (string format, Action, NSError> completionHandler); +#if !XAMCORE_5_0 + [Obsolete ("Call 'LoadTrack2' instead.")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTrackWithTrackID:completionHandler:")] void LoadTrack (int trackId, Action completionHandler); +#endif + + [Async] + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTrackWithTrackID:completionHandler:")] +#if XAMCORE_5_0 + void LoadTrack (int trackId, AVAssetLoadTrackCallback completionHandler); +#else + [Sealed] + void LoadTrack2 (int trackId, AVAssetLoadTrackCallback completionHandler); +#endif +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTrackWithMediaCharacteristics (..., AVAssetLoadTracksCallback)' overload instead (or the 'LoadTrackWithMediaCharacteristics2Async' method).")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] void LoadTrackWithMediaCharacteristics (string mediaCharacteristic, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTrackWithMediaCharacteristics2Async")] + [Sealed] +#endif + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] + void LoadTrackWithMediaCharacteristics (string mediaCharacteristic, AVAssetLoadTracksCallback completionHandler); +#if !XAMCORE_5_0 + [Obsolete ("Call 'LoadTracksWithMediaType (..., AVAssetLoadTracksCallback)' instead (or the 'LoadTracksWithMediaType' method).")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaType:completionHandler:")] void LoadTracksWithMediaType (string mediaType, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaType2Async")] + [Sealed] +#endif + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaType:completionHandler:")] + void LoadTracksWithMediaType (string mediaType, AVAssetLoadTracksCallback completionHandler); + + [Wrap ("LoadTracksWithMediaType (mediaType.GetConstant ()!, completionHandler)")] + void LoadTracksWithMediaType (AVMediaTypes mediaType, AVAssetLoadTracksCallback completionHandler); } + delegate void AVAssetLoadTrackCallback ([NullAllowed] AVAssetTrack track, [NullAllowed] NSError error); + delegate void AVAssetLoadTracksCallback ([NullAllowed] AVAssetTrack [] tracks, [NullAllowed] NSError error); + interface IAVFragmentMinding { } /// Interface for to support tracking whether fragments have been appended to a fragmented asset. @@ -12657,22 +12702,66 @@ interface AVMovie_AVMovieTrackInspection { [Wrap ("This.GetTracksWithMediaCharacteristic (mediaCharacteristic.GetConstant ()!)")] AVMovieTrack [] GetTracks (AVMediaCharacteristics mediaCharacteristic); +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTrack (..., AVMovieLoadTracksCallback)' overload instead (or the 'LoadTrack2Async' method).")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTrackWithTrackID:completionHandler:")] void LoadTrack (int trackId, Action completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTrack2Async")] +#endif + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTrackWithTrackID:completionHandler:")] + void LoadTrack (int trackId, AVMovieLoadTrackCallback completionHandler); +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaType (..., AVMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaType2Async' method).")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaType:completionHandler:")] void LoadTracksWithMediaType (string mediaType, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaType2Async")] +#endif + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaType:completionHandler:")] + void LoadTracksWithMediaType (string mediaType, AVMovieLoadTracksCallback completionHandler); + [Async] + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Wrap ("This.LoadTracksWithMediaType (mediaType.GetConstant ()!, completionHandler)")] + void LoadTracksWithMediaType (AVMediaTypes mediaType, AVMovieLoadTracksCallback completionHandler); + +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaCharacteristic (..., AVMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaCharacteristic2Async' method).")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaCharacteristic2Async")] +#endif + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] + void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, AVMovieLoadTracksCallback completionHandler); } + delegate void AVMovieLoadTrackCallback ([NullAllowed] AVMovieTrack track, [NullAllowed] NSError error); + delegate void AVMovieLoadTracksCallback ([NullAllowed] AVMovieTrack [] tracks, [NullAllowed] NSError error); + [NoTV, iOS (13, 0)] [MacCatalyst (13, 1)] [BaseType (typeof (AVMovie))] @@ -12736,20 +12825,64 @@ interface AVMutableMovie { [Export ("interleavingPeriod", ArgumentSemantic.Assign)] CMTime InterleavingPeriod { get; set; } +#if !XAMCORE_5_0 + [Obsolete ("Call 'LoadTrack2' instead.")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTrackWithTrackID:completionHandler:")] void LoadTrack (int trackId, Action completionHandler); +#endif + + [Async] + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTrackWithTrackID:completionHandler:")] +#if XAMCORE_5_0 + void LoadTrack (int trackId, AVMutableMovieLoadTrackCallback completionHandler); +#else + [Sealed] + void LoadTrack2 (int trackId, AVMutableMovieLoadTrackCallback completionHandler); +#endif +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaType (..., AVMutableMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaCharacteristic2Async' method).")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaType:completionHandler:")] void LoadTracksWithMediaType (string mediaType, Action, NSError> completionHandler); +#endif +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaType2Async")] + [Sealed] +#endif + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaType:completionHandler:")] + void LoadTracksWithMediaType (string mediaType, AVMutableMovieLoadTracksCallback completionHandler); + + [Async] + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Wrap ("LoadTracksWithMediaType (mediaType.GetConstant ()!, completionHandler)")] + void LoadTracksWithMediaType (AVMediaTypes mediaType, AVMutableMovieLoadTracksCallback completionHandler); + +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaCharacteristic (..., AVMutableMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaCharacteristic2Async' method).")] [Async] [NoTV, iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaCharacteristic2Async")] + [Sealed] +#endif + [NoTV, iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] + void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, AVMutableMovieLoadTracksCallback completionHandler); // inlined from the AVMutableMovie (SynchronousAssetInterface) category [Export ("metadataForFormat:")] @@ -12773,6 +12906,9 @@ interface AVMutableMovie { int GetUnusedTrackId (); } + delegate void AVMutableMovieLoadTrackCallback ([NullAllowed] AVMutableMovieTrack track, [NullAllowed] NSError error); + delegate void AVMutableMovieLoadTracksCallback ([NullAllowed] AVMutableMovieTrack [] tracks, [NullAllowed] NSError error); + [NoTV, iOS (13, 0)] [MacCatalyst (13, 1)] [Category] @@ -12973,22 +13109,66 @@ interface AVFragmentedMovie_AVFragmentedMovieTrackInspection { [Wrap ("This.GetTracksWithMediaCharacteristic (mediaCharacteristic.GetConstant ()!)")] AVFragmentedMovieTrack [] GetTracks (AVMediaCharacteristics mediaCharacteristic); +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTrack (..., AVFragmentedMovieLoadTrackCallback)' overload instead (or the 'LoadTrack2Async' method).")] [Async] [iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTrackWithTrackID:completionHandler:")] void LoadTrack (int trackId, Action completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTrack2Async")] +#endif + [iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTrackWithTrackID:completionHandler:")] + void LoadTrack (int trackId, AVFragmentedMovieLoadTrackCallback completionHandler); +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaType (..., AVFragmentedMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaType2Async' method).")] [Async] [iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaType:completionHandler:")] void LoadTracksWithMediaType (string mediaType, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaType2Async")] +#endif + [iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaType:completionHandler:")] + void LoadTracksWithMediaType (string mediaType, AVFragmentedMovieLoadTracksCallback completionHandler); + [Async] + [iOS (15, 0), MacCatalyst (15, 0)] + [Wrap ("This.LoadTracksWithMediaType (mediaType.GetConstant ()!, completionHandler)")] + void LoadTracksWithMediaType (AVMediaTypes mediaType, AVFragmentedMovieLoadTracksCallback completionHandler); + +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaCharacteristic (..., AVFragmentedMovieLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaCharacteristic2Async' method).")] [Async] [iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaCharacteristic2Async")] +#endif + [iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] + void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, AVFragmentedMovieLoadTracksCallback completionHandler); } + delegate void AVFragmentedMovieLoadTrackCallback ([NullAllowed] AVFragmentedMovieTrack track, [NullAllowed] NSError error); + delegate void AVFragmentedMovieLoadTracksCallback ([NullAllowed] AVFragmentedMovieTrack [] tracks, [NullAllowed] NSError error); + [iOS (13, 0), NoTV] [MacCatalyst (13, 1)] [BaseType (typeof (AVFragmentedAssetMinder))] @@ -13563,22 +13743,66 @@ interface AVComposition_AVCompositionTrackInspection { [Wrap ("This.GetTracksWithMediaCharacteristic (mediaCharacteristic.GetConstant ()!)")] AVCompositionTrack [] GetTracks (AVMediaCharacteristics mediaCharacteristic); +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTrack (..., AVCompositionLoadTrackCallback)' overload instead (or the 'LoadTrack2Async' method).")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTrackWithTrackID:completionHandler:")] void LoadTrack (int trackId, Action completionHandler); +#endif +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTrack2Async")] +#endif + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTrackWithTrackID:completionHandler:")] + void LoadTrack (int trackId, AVCompositionLoadTrackCallback completionHandler); + +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaType (..., AVCompositionLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaType' method).")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaType:completionHandler:")] void LoadTracksWithMediaType (string mediaType, Action, NSError> completionHandler); +#endif +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaType2Async")] +#endif + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaType:completionHandler:")] + void LoadTracksWithMediaType (string mediaType, AVCompositionLoadTracksCallback completionHandler); + + [Async] + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Wrap ("This.LoadTracksWithMediaType (mediaType.GetConstant ()!, completionHandler)")] + void LoadTracksWithMediaType (AVMediaTypes mediaType, AVCompositionLoadTracksCallback completionHandler); + +#if !XAMCORE_5_0 + [Obsolete ("Call the 'LoadTracksWithMediaCharacteristic (..., AVCompositionLoadTracksCallback)' overload instead (or the 'LoadTracksWithMediaCharacteristic' method).")] [Async] [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, Action, NSError> completionHandler); +#endif + +#if XAMCORE_5_0 + [Async] +#else + [Async ("LoadTracksWithMediaCharacteristic2Async")] +#endif + [TV (15, 0), iOS (15, 0), MacCatalyst (15, 0)] + [Export ("loadTracksWithMediaCharacteristic:completionHandler:")] + void LoadTracksWithMediaCharacteristic (string mediaCharacteristic, AVCompositionLoadTracksCallback completionHandler); } + delegate void AVCompositionLoadTrackCallback ([NullAllowed] AVCompositionTrack track, [NullAllowed] NSError error); + delegate void AVCompositionLoadTracksCallback ([NullAllowed] AVCompositionTrack [] tracks, [NullAllowed] NSError error); + [MacCatalyst (13, 1)] [BaseType (typeof (AVComposition))] interface AVMutableComposition { diff --git a/tests/monotouch-test/AVFoundation/AVAssetLoadTracksTest.cs b/tests/monotouch-test/AVFoundation/AVAssetLoadTracksTest.cs new file mode 100644 index 000000000000..0079b4716eb7 --- /dev/null +++ b/tests/monotouch-test/AVFoundation/AVAssetLoadTracksTest.cs @@ -0,0 +1,414 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.IO; +using System.Threading.Tasks; + +using AVFoundation; +using CoreMedia; + +#nullable enable + +namespace MonoTouchFixtures.AVFoundation { + + [TestFixture] + [Preserve (AllMembers = true)] + public class AVAssetLoadTracksTest { + + static string VideoPath => Path.Combine (NSBundle.MainBundle.ResourcePath, "xamvideotest.mp4"); + + #region AVAsset + + [Test] + public void AVAsset_LoadTrack2 () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + + var tcs = new TaskCompletionSource (); + asset.LoadTrack2 (1, (track, error) => { + tcs.TrySetResult (track); + }); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) + Assert.That (result, Is.InstanceOf (), "result type"); + } + + [Test] + public void AVAsset_LoadTrackWithMediaCharacteristics () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + + var tcs = new TaskCompletionSource (); + asset.LoadTrackWithMediaCharacteristics (AVMediaCharacteristics.Visual.GetConstant ()!, (tracks, error) => { + tcs.TrySetResult (tracks); + }); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + [Test] + public void AVAsset_LoadTracksWithMediaType () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + + var tcs = new TaskCompletionSource (); + asset.LoadTracksWithMediaType (AVMediaTypes.Video.GetConstant ()!, (AVAssetLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + [Test] + public void AVAsset_LoadTracksWithMediaType_Enum () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + + var tcs = new TaskCompletionSource (); + asset.LoadTracksWithMediaType (AVMediaTypes.Video, (AVAssetLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + #endregion + + #region AVMovie +#if !__TVOS__ + + [Test] + public void AVMovie_LoadTrack () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMovie (url, (NSDictionary?) null); + + var tcs = new TaskCompletionSource (); + movie.LoadTrack (1, (AVMovieLoadTrackCallback) ((track, error) => { + tcs.TrySetResult (track); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) + Assert.That (result, Is.InstanceOf (), "result type"); + } + + [Test] + public void AVMovie_LoadTracksWithMediaType () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMovie (url, (NSDictionary?) null); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaType (AVMediaTypes.Video.GetConstant ()!, (AVMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + // mp4 files may not be recognized as movies, so tracks could be null + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + + [Test] + public void AVMovie_LoadTracksWithMediaType_Enum () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMovie (url, (NSDictionary?) null); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaType (AVMediaTypes.Video, (AVMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + + [Test] + public void AVMovie_LoadTracksWithMediaCharacteristic () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMovie (url, (NSDictionary?) null); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaCharacteristic (AVMediaCharacteristics.Visual.GetConstant ()!, (AVMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + +#endregion + + #region AVMutableMovie + + [Test] + public void AVMutableMovie_LoadTrack2 () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMutableMovie (url, (NSDictionary?) null, out var initError); + if (initError is not null) + Assert.Ignore ($"Could not create AVMutableMovie from test file: {initError.LocalizedDescription}"); + + var tcs = new TaskCompletionSource (); + movie.LoadTrack2 (1, (track, error) => { + tcs.TrySetResult (track); + }); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) + Assert.That (result, Is.InstanceOf (), "result type"); + } + + [Test] + public void AVMutableMovie_LoadTracksWithMediaType () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMutableMovie (url, (NSDictionary?) null, out var initError); + if (initError is not null) + Assert.Ignore ($"Could not create AVMutableMovie from test file: {initError.LocalizedDescription}"); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaType (AVMediaTypes.Video.GetConstant ()!, (AVMutableMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + + [Test] + public void AVMutableMovie_LoadTracksWithMediaType_Enum () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMutableMovie (url, (NSDictionary?) null, out var initError); + if (initError is not null) + Assert.Ignore ($"Could not create AVMutableMovie from test file: {initError.LocalizedDescription}"); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaType (AVMediaTypes.Video, (AVMutableMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + + [Test] + public void AVMutableMovie_LoadTracksWithMediaCharacteristic () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var movie = new AVMutableMovie (url, (NSDictionary?) null, out var initError); + if (initError is not null) + Assert.Ignore ($"Could not create AVMutableMovie from test file: {initError.LocalizedDescription}"); + + var tcs = new TaskCompletionSource (); + movie.LoadTracksWithMediaCharacteristic (AVMediaCharacteristics.Visual.GetConstant ()!, (AVMutableMovieLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + if (result is not null) { + Assert.That (result.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + } + +#endif // !__TVOS__ + #endregion + + #region AVComposition + + [Test] + public void AVComposition_LoadTrack () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + using var composition = AVMutableComposition.Create (); + + var compositionTrack = composition.AddMutableTrack (AVMediaTypes.Video.GetConstant ()!, 0); + if (compositionTrack is null) + Assert.Ignore ("Could not add track to composition"); + + var sourceTracks = asset.GetTracks (AVMediaTypes.Video); + if (sourceTracks.Length == 0) + Assert.Ignore ("No video tracks in source asset"); + + compositionTrack.InsertTimeRange (new CMTimeRange { Start = CMTime.Zero, Duration = asset.Duration }, sourceTracks [0], CMTime.Zero, out _); + + var trackId = compositionTrack.TrackID; + var tcs = new TaskCompletionSource (); + composition.LoadTrack (trackId, (AVCompositionLoadTrackCallback) ((track, error) => { + tcs.TrySetResult (track); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result, Is.InstanceOf (), "result type"); + } + + [Test] + public void AVComposition_LoadTracksWithMediaType () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + using var composition = AVMutableComposition.Create (); + + var compositionTrack = composition.AddMutableTrack (AVMediaTypes.Video.GetConstant ()!, 0); + if (compositionTrack is null) + Assert.Ignore ("Could not add track to composition"); + + var sourceTracks = asset.GetTracks (AVMediaTypes.Video); + if (sourceTracks.Length == 0) + Assert.Ignore ("No video tracks in source asset"); + + compositionTrack.InsertTimeRange (new CMTimeRange { Start = CMTime.Zero, Duration = asset.Duration }, sourceTracks [0], CMTime.Zero, out _); + + var tcs = new TaskCompletionSource (); + composition.LoadTracksWithMediaType (AVMediaTypes.Video.GetConstant ()!, (AVCompositionLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + [Test] + public void AVComposition_LoadTracksWithMediaType_Enum () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + using var composition = AVMutableComposition.Create (); + + var compositionTrack = composition.AddMutableTrack (AVMediaTypes.Video.GetConstant ()!, 0); + if (compositionTrack is null) + Assert.Ignore ("Could not add track to composition"); + + var sourceTracks = asset.GetTracks (AVMediaTypes.Video); + if (sourceTracks.Length == 0) + Assert.Ignore ("No video tracks in source asset"); + + compositionTrack.InsertTimeRange (new CMTimeRange { Start = CMTime.Zero, Duration = asset.Duration }, sourceTracks [0], CMTime.Zero, out _); + + var tcs = new TaskCompletionSource (); + composition.LoadTracksWithMediaType (AVMediaTypes.Video, (AVCompositionLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + [Test] + public void AVComposition_LoadTracksWithMediaCharacteristic () + { + TestRuntime.AssertXcodeVersion (13, 0); + + using var url = NSUrl.FromFilename (VideoPath); + using var asset = AVAsset.FromUrl (url); + using var composition = AVMutableComposition.Create (); + + var compositionTrack = composition.AddMutableTrack (AVMediaTypes.Video.GetConstant ()!, 0); + if (compositionTrack is null) + Assert.Ignore ("Could not add track to composition"); + + var sourceTracks = asset.GetTracks (AVMediaTypes.Video); + if (sourceTracks.Length == 0) + Assert.Ignore ("No video tracks in source asset"); + + compositionTrack.InsertTimeRange (new CMTimeRange { Start = CMTime.Zero, Duration = asset.Duration }, sourceTracks [0], CMTime.Zero, out _); + + var tcs = new TaskCompletionSource (); + composition.LoadTracksWithMediaCharacteristic (AVMediaCharacteristics.Visual.GetConstant ()!, (AVCompositionLoadTracksCallback) ((tracks, error) => { + tcs.TrySetResult (tracks); + })); + + Assert.That (tcs.Task.Wait (TimeSpan.FromSeconds (10)), Is.True, "Timed out"); + var result = tcs.Task.Result; + Assert.That (result, Is.Not.Null, "result"); + Assert.That (result!.Length, Is.GreaterThan (0), "result.Length"); + Assert.That (result [0], Is.InstanceOf (), "result[0] type"); + } + + #endregion + } +}