0

I have Qt application, I'm calling UIImagePickerController to get file path for movie the user selected. So I have static functions in Objective-C which call functions from .m file, when user selects movie I can read selected path in another .m function. Question is, how to get this filePath into some Objective-C class where I can call another Qt classes (like Singleton) and pass this result to proper class ? Objective-C CL_image_call.mm

#include "cl_image_call.h"
#include "cl_image_func.h"

myCLImageClass* CL_image_obj=NULL;

int CL_ImageCCall::CL_objectiveC_Call() {
  //Objective C code calling..... 
    if( CL_image_obj==NULL ) {
      //Allocating the new object for the objective C class we created
        CL_image_obj=[[myCLImageClass alloc]init]; 
    }
  return 1;
}
void CL_ImageCCall::CL_openMedia() {
    [CL_image_obj openMedia];
}

CL_image_call.h

#include <QImage>
#include <QString>
#include <QDebug>
#include <stdio.h>
#include "my_singleton.h"

class CL_ImageCCall
{
  public:
    static int CL_objectiveC_Call(); 
    static void CL_openMedia();  
};

CL_image_func.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface myCLImageClass:NSObject
-(void)openMedia;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
@end

CL_image_func.m

#import "cl_image_func.h"

@interface QIOSViewController : UIViewController
@end

@implementation myCLImageClass
UIImagePickerController *picker=NULL;
UIViewController *viewController=NULL;
NSString *f_path;

-(void)openMedia {
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    
    viewController = (UIViewController *)([keyWindow rootViewController]);
        if (!viewController)
            return;
    
    if([UIImagePickerController isSourceTypeAvailable:
                            UIImagePickerControllerSourceTypePhotoLibrary]) {

         picker= [[UIImagePickerController alloc] init];
         picker.delegate = self;
         picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
         picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];

         [viewController presentViewController:picker animated:YES completion:NULL];
    }
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath =  [docDirPath stringByAppendingPathComponent:@"movie.mov"];
    NSLog (@"File Path = %@", filePath);
    //filePath is what I need to pass to the rest of my app
    
    [viewController dismissViewControllerAnimated:YES completion:nil];
}

So in CL_image_call.h I have my "my_singleton" where I can reach my whole app, but how to get filePath to this class ?

Best Regards

Marek

user2018761
  • 306
  • 5
  • 14
  • I guess you need to export the media from album and store in your sandbox somewhere, and you can use the filePath to visit the media and do what you want? – childrenOurFuture Jun 17 '21 at 12:30

2 Answers2

2

Here is the code to export media:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath =  [docDirPath stringByAppendingPathComponent:@"movie.mov"];
    NSLog (@"File Path = %@", filePath);
    //filePath is what I need to pass to the rest of my app
    NSURL *inputURL  = [info objectForKey:UIImagePickerControllerMediaURL];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    // config the session, maybe some option is not what you need, just config by what you need
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
                                                                     presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = [NSURL fileURLWithPath:filePath];
    session.outputFileType = AVFileTypeMPEG4;
    session.shouldOptimizeForNetworkUse = YES;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
     {
        // do a completion handler
    }];
    
    [viewController dismissViewControllerAnimated:YES completion:nil];
}

Then you can visit the output by the filePath, and use when you need.

childrenOurFuture
  • 1,889
  • 2
  • 14
  • 23
  • I wanted to post code in my answer, and comment has too little space, true I could change my original question including your answer but it seemed odd to me – user2018761 Jun 18 '21 at 09:50
0

I have modified code with your suggestion and it does what it should. I'm settings moviePath inside my Qt classes and then I call Objective-C code with this path

NSString *f_path;
  //Your objective c code here....

-(void)openMedia:(NSString*)moviePath {
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    
    f_path=moviePath.copy;
    viewController = (UIViewController *)([keyWindow rootViewController]);
        if (!viewController)
            return;
    if([UIImagePickerController isSourceTypeAvailable:
                            UIImagePickerControllerSourceTypePhotoLibrary]) {

         picker= [[UIImagePickerController alloc] init];
         picker.delegate = self;
         picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
         picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];

         [viewController presentViewController:picker animated:YES completion:NULL];
        
    }
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSURL *inputURL  = [info objectForKey:UIImagePickerControllerMediaURL];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    // config the session, maybe some option is not what you need, just config by what you need
    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
                                                                         presetName:AVAssetExportPresetMediumQuality];
    session.outputURL = [NSURL fileURLWithPath:f_path];
    session.outputFileType = AVFileTypeMPEG4;
    session.shouldOptimizeForNetworkUse = YES;
    [session exportAsynchronouslyWithCompletionHandler:^(void)
    {
        // do a completion handler
        NSLog (@"export complete = %@", f_path);
    }];
    
    [viewController dismissViewControllerAnimated:YES completion:nil];
}

with some trick I can view this movie inside Qt app. One thing that is missing: I need to know somehow that session has been completed, to refresh file path for MediaPlayer. How can I notify my base class CL_ImageCCall about that. Or actually maybe another Objective-C++ class where I can actually mix Qt and Objective-C ?

Best Regards and thanks for Your help

Marek

user2018761
  • 306
  • 5
  • 14
  • block in exportAsynchronouslyWithCompletionHandler is the callback after completed, post a notification or other way to inform your media player, that would be ok – childrenOurFuture Jun 18 '21 at 12:18
  • yes I know this block waits until session is completed. Maybe this is Qt related question. I don't have access from .m file functions to my Qt/C++ classes. If I add something in CL_image_func.h file like #include "my_singleton.h" (my C++ singleton) compilation fails with 20 errors from basic Qt classes. Is there a way for example to use some iOS specific way to notify static class CL_image_call where I initialize CL_image_obj=[[myCLImageClass alloc]init] that imagePicker has finished ? – user2018761 Jun 18 '21 at 14:10
  • also solution for me would be if I could write all iOS code inside .mm files. Is it possible to move -(void)openMedia:(NSString*)moviePath - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info Into .mm files ? – user2018761 Jun 18 '21 at 15:21
  • have you try to make CL_image_func.m rename to CL_image_func.mm? https://stackoverflow.com/questions/4562255/xcode-m-vs-mm – childrenOurFuture Jun 19 '21 at 02:12
  • Thanks man it works excellent after this change. Best Regards – user2018761 Jun 23 '21 at 10:35