Getting a null uiimage when trying to generate a thumbnail

wallymwallym ✭✭✭USInsider, Beta ✭✭✭
edited February 2015 in Xamarin.iOS

I've got a UIViewController where I am allowing a user to select a video that is on their device. I would like to generate a thumbnail from the video to present that to the user to verify that the file has been selected. Unfortunately, I am getting a null image. The code is below. The video is a mov file that is selected from on the device. When I step through my code below, I get to CopyCGImageAtTime method, and the out param for the error merely gives me "unknown error." I know that the image video comes back would be a file that exists, or the code would return out. I wonder about the CMTime object, if I am setting it up correctly. I am just guessing what the format value (second value) should be. I found an example with 1 and another with 100, neither seemed to work for me. Suggestions are appreciated. Thanks.

            if ( !System.IO.File.Exists(media.Path) )  
            {  
                return;  
            }  
            AVFoundation.AVAsset asset = AVFoundation.AVAsset.FromUrl(NSUrl.FromString(media.Path));  
            AVFoundation.AVAssetImageGenerator imgGen = AVFoundation.AVAssetImageGenerator.FromAsset(asset);  
            CoreMedia.CMTime ActTime;  
            NSError err;  
            var imageRef = imgGen.CopyCGImageAtTime(CoreMedia.CMTime.FromSeconds(0, 100),   
                out ActTime, out err);  
            var movieImage = UIImage.FromImage(imageRef);  

            uiivVideo.Image = movieImage;  

Posts

  • wallymwallym ✭✭✭ USInsider, Beta ✭✭✭

    Just a little more info on this. I've tried this under iOS7 as well as iOS8. I've tried this on an 4s as well as a 6+. I've tried this with multiple video files that have been captured on both devices (4s & 6+). Any thoughts are welcome.

    PS. Been away due to sickness.

  • GlennStephens.8241GlennStephens.8241 Xamurai AUXamarin Team, University, XamUProfessors, Developer Group Leader Xamurai

    Hey Wally,

    Try this. This is some old code, but I normally check for non-null values and display an alternative thumbnail. It's mainly the AppliesPreferredTrackTransform and the CMTime where I see the main difference

    UIImage GetVideoDetailsFromFile (string filename)
    {
    try
    {
    var url = NSUrl.FromString (filename);
    var asset = AVAsset.FromUrl (url);

        var t = TimeSpan.FromSeconds( Convert.ToInt32(asset.Duration.Seconds));
        Length = string.Format("{0:D2}:{1:D2}:{2:D2}", t.Hours, t.Minutes, t.Seconds);
    
        if (url.IsFileUrl)
        {
            var fs = new FileInfo (url.Path);
            var filesize = fs.Length / 1024;
            if (filesize < 1024) 
                this.Size = filesize + "Kb";
            else
            {
                var sizeInMB = Convert.ToDouble(filesize / 1024);
                this.Size = sizeInMB.ToString ("##.##") + "Mb";
            }
        }
    
        CMTime time = new CMTime (0, 1);
        CMTime actualTime;
        NSError outError;
    
        using (var imageGenerator = AVAssetImageGenerator.FromAsset (asset))
        {
            imageGenerator.AppliesPreferredTrackTransform = true;
    
            using (var imageRef = imageGenerator.CopyCGImageAtTime (time, out actualTime, out outError)) {
                Thumbnail = UIImage.FromImage (imageRef);
            }
        }
    } catch (Exception assetException){
        Logger.LogError (assetException); // A personal logging library. You'll need to switch this
        Thumbnail = null;
    }
    

    }

  • wallymwallym ✭✭✭ USInsider, Beta ✭✭✭

    Glenn,

    Thanks. I've tried just about everything but am not getting any love with this. I've tried just about everything. It feels like it is a permission problem like I don't have access to the video file somehow.

    I decided to take your code and massage it just a bit, but I still get the same result. Here is what I am doing:
    UIImage GetVideoDetailsFromFile (string filename)
    {
    UIImage thumbNail = null;
    try
    {
    var url = NSUrl.FromString (filename);
    var asset = AVAsset.FromUrl (url);

                var t = TimeSpan.FromSeconds( Convert.ToInt32(asset.Duration.Seconds));  
    
                CMTime time = new CMTime (0, 1);  
                CMTime actualTime;  
                NSError outError;  
    
                using (var imageGenerator = AVAssetImageGenerator.FromAsset (asset))  
                {  
                    imageGenerator.AppliesPreferredTrackTransform = true;  
    
                    using (var imageRef = imageGenerator.CopyCGImageAtTime (time, out actualTime, out outError)) {  
                        thumbNail = UIImage.FromImage (imageRef);  
                    }  
                }  
            } catch (Exception assetException){  
                thumbNail = null;  
            }  
            return thumbNail;  
        }  
    

    I'm using Xamarin.Mobile to get the video and then using the .Path property to get the file name. The resulting file name with Path information is
    /var/mobile/Containers/Data/Application/1A0A7EE9-2E41-4F6F-A7D8-0CACF19E1D3D/Documents/temp/trim.6B59CE14-C4BC-47B2-A465-399CA559835B.MOV
    Does this look correct?

    I apologize for being away. Been sick and then we had an ice storm, snow, and cold (well cold for around here).

    Wally

  • NuninzNuninz ✭✭ USMember ✭✭

    Hi @wallym , did you figure it out why is not working? I was trying to do the same but with no success so far

  • SplinterCellSplinterCell ✭✭ ATMember ✭✭

    Hi, same question here, get anyone this method running ?
    thx guys

  • DanRichardsonDanRichardson ✭✭ USMember ✭✭

    It's a bit late, but hopefully will help someone:

    I was having the same issue. I fixed it using Danny C's solution, found here:
    https://forums.xamarin.com/discussion/61903/code-snippet-how-to-generate-video-thumbnail

    The code is exactly the same, except that the NSUrl variable is generated using NSUrl.FromFilename(path). That fixed it for me.

  • EliasRMLJEliasRMLJ Member

    Show wallym. Here is fine

Sign In or Register to comment.