Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

Writing MetaData using AVAssetExportSession

$
0
0

Hi All,

I have been trying to complete an application that reads and updates metadata for a variety of A/V files and have been successfully using the taglib library for most media files. However, since taglib does not support QuickTime .mov files I have been using the QTKit and the AVAssetExportSession methods to work on the QuickTime files. I can successfully obtain all metadata information from any QuickTime source file but no matter how I have worked with the Export Session functions, I am unable to change any of the metadata in the destination file. I will provide code snippets to show what I have done.

First, I obtain the videoAsset from the source file, obtain the basic metadata information about it, create two internal lists for subsquent display and initialize the destination file information, and create an array of metadata items for later assignment:

        AVUrlAsset videoAsset = new AVUrlAsset (NSUrl.FromFilename(lblImagePath.StringValue), new NSDictionary());
        int metaItems = videoAsset.CommonMetadata.Length;
        AVMetadataItem metaItem;

        metaList = new List<MetaDataItems> ();
        metaListAV = new List<AVMetadataItem> ();


        string newFileName = Path.GetFileName (lblImagePath.StringValue);
        newFileName = "Copy-" + newFileName;

        string directoryName = Path.GetDirectoryName (lblImagePath.StringValue);

        string videoOutFilePath = Path.Combine (directoryName, newFileName);

        AVMutableMetadataItem [] avMMetadataItemArray = new AVMutableMetadataItem[videoAsset.CommonMetadata.Length];

Now I assign all the metadata fields in the array with those from the source file:

        for (int i = 0; i < metaItems; i++) {

            AVMutableMetadataItem mutItem = new AVMutableMetadataItem ();
            MetaDataItems mItem = new MetaDataItems ();

            NSObject obj = NSObject.FromObject ("this is the newest title");  // Change the value for testing


            metaItem = videoAsset.CommonMetadata [i];

            mItem.Key = metaItem.Key;
            mItem.Value = metaItem.Value;

            mutItem.KeySpace = AVMetadata.KeySpaceCommon;   //AVMetadataKeySpaceCommon;
            mutItem.Key = mItem.Key;
            mutItem.Value = mItem.Value;
            avMMetadataItemArray [i] = (AVMutableMetadataItem)videoAsset.CommonMetadata [i];

            if (metaItem.Value.ToString() == "Title Name") {
                avMMetadataItemArray [i].Value = obj;
            }
            metaList.Add (mItem);
            metaListAV.Add (mutItem);
        }

At this point, if I compare the source metadata items against the newly assigned avMMetadataItemArray, they appear identical, except for the Title field which I used as a test to change the value. See the attached file metaCompare.png.

Finally, I now setup the Export, provide a completion handler and do the export:

        error = null;
        AVAssetExportSession assetExport = new AVAssetExportSession(videoAsset, "AVAssetExportPresetPassthrough");
        assetExport.OutputFileType = AVFileType.QuickTimeMovie;
        assetExport.OutputUrl = NSUrl.FromFilename(videoOutFilePath);

        assetExport.Metadata = avMMetadataItemArray; // Leaving this out creates the destination with original meta intact

        assetExport.ShouldOptimizeForNetworkUse = true;

        AVCompletionHandler handler = new AVCompletionHandler(delegate () {
            AVAssetExportSessionStatus status = assetExport.Status;
            Console.WriteLine("Done with handler. Status: " + status.ToString());
            if(File.Exists(videoOutFilePath)) {
                Console.WriteLine("Created!!");
            }
            else
                Console.WriteLine("Failed");
            //AVAssetExportSessionStatus
        });

        assetExport.ExportAsynchronously (handler);

The result of this creates the destination file, it will play, but all the metadata is empty except for the Title which contains the file name! (See attachment wrongMetadata.png. If, however, I comment out the assignment metadata line, assetExport.Metadata, the destination file contains all the metadata from the source, intact! See attached correctMetadata.png. The handler, in both cases always returns with successfully completed.

I must be doing something wrong. I have scoured the web, all over stackoverflow, and although there are some examples in objective-c, there is nothing available in Xamarin for Mac. I modeled this along the lines of what I could see in some of the examples, but have not been able to successfully save the updated metadata.

I would be eternally grateful if anyone can assist!

Thanks in advance,

Bob


Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>