How to get frame data in AppRTC iOS app for video modifications? - swift

I am currently trying to make some modifications to the incoming WebRTC video stream in the AppRTC app for iOS in Swift (which in turn is based on this Objective-C version). To do so, I need access to the data which is stored in the frame objects of class RTCI420Frame (which is a basic class for the Objective-C implementation of libWebRTC). In particular, I need an array of bytes: [UInt8] and Size of the frames. This data is to be used for further processing & addition of some filters.
The problem is, all the operations on RTCVideoTrack / RTCEAGLVideoView are done under the hood of pre-compiled libWebRTC.a, it is compiled from the official WebRTC repository linked above and it's fairly complicated to get a custom build of it, so I'd prefer to go with the build available in the example iOS project; in my understanding it's supposed to have all the available functionality in it.
I was looking into RTCVideoChatViewController class and in particular, remoteView / remoteVideoTrack, but had no success in accessing the frames themselves, spent a lot of time researching the libWebRTC sources in official repo but still can't wrap my head around the problem of accessing the frames data for own manipulations with it. Would be glad for any help!

Just after posting the question I had a luck in finding the sneaky data!
You have to add the following property to RTCEAGLVideoView.h file:
#property(atomic, strong) RTCI420Frame* i420Frame;
In the original implementation file there is the i420Frame property but it wasn't exposed in the iOS project's header file for the class. Adding the property allows you to get view's current frame.
I'm still in search of a more elegant way of getting the stream data directly, without the need to look into remoteView contents, will update the answer once I find it.

Related

reuse result of initialize method from video_player flutter package

Is there option to reuse result of initialize method for video_player package? It takes time for complete - it would be great to cache it (eg. memory level) and reuse it when you back to before used video - and simple use cached data instead of wait for initialize result. I need it for intensive switching between videos.
There is a package called cached_video_player which may help resolve your problem. Check it out here.
I think you are asking about having the screen/page/widget pre-render. That is not currently supported by flutter according to this issue filed on github:
https://github.com/flutter/uxr/issues/6#issuecomment-881918751
Sure, but this is not very scalable and will quickly turn into a mess. It's much simpler and more flexible to just give MyRoute someway it can cache the next route, and then show that cached route when it needs. But flutter doesn't support this as everything needs to be 'on-stage' before it can be initialized. In AIR, or Unity, I could simply construct my new page, and it would begin loading data, I could then toss it on stage whenever I want.
PS. You probably already know you can pre-cache the video data/file itself.

How to clear/invalidate ambient cache on iOS app

When I update tilesets on mapbox, changes don't appear in the iOS app unless I re-install it. There is seemingly documentation on this here: https://docs.mapbox.com/ios/api/maps/5.2.0/Classes/MGLOfflineStorage.html#/c:objc(cs)MGLOfflineStorage(im)setMaximumAmbientCacheSize:withCompletionHandler: but I can't figure out how exactly to implement it. I don't have an MGLOfflineStorage object because I am not worried about offline map storage right now, I just want to refresh the cache in the app. There are good examples of how to do this in android, but not on iOS. Any help is appreciated (preferably in swift)
It appears to be correct to call the methods on the shared MGLOfflineStorage object. The method parameter should be a closure containing any code you want to execute upon completion.
MGLOfflineStorage.shared.invalidateAmbientCache { error in
print("Invalidated")
}
Naturally you should check the error in the usual 'safe' way.

How do I retrieve a list of my downloaded offline map packs using Mabox and Swift?

I am wanting to add offline map functionality to an iOS app build using Swift and Mapbox. There is great documentation and examples for downloading a map region pack, but am having a difficult time figuring out how to retrieve a list of offline packs. Their documentation here gives these instructions on how to receive:
"To detect when the shared offline storage object has finished loading its packs property, observe KVO change notifications on the packs key path. The initial load results in an NSKeyValueChangeSetting change."
But I am having a difficult time find any examples or explanations as to what that means. Any help would be greatly appreciated!
An array of all known offline packs can be retrieved using the .packs attribute of the MGLOfflineStorage class. Like so:
MGLOfflineStorage.shared.packs
To access these packs, you just need to iterate over the array or pass a specific index and retrieve whatever information you're interested in from the packs.
There is a good example of using this array to create a tableview of the completed offline packs on a device in the SDK's open source test app (NB: this example is written in Obj-C).
⚠️ Disclaimer: I currently work at Mabpox ⚠️
I was finally able to come to a solution. To observe the packs retrieval using Swift, you can use this code:
MGLOfflineStorage.shared.observe(\.packs, options: [.new, .old]){ object, change in
var offlinePacksArr : [MGLOfflinePack] = object.packs // Access to packs array here
}

UIManagedDocument example / tutorial

I have been trying very unsuccessfully to create a simple UIManagedDocument library style application (separate documents saved to iCloud).
I am confused with the following:
Do I subclass UIManagedDocument and set up the persistentStoreCoordinator, ManagedObjectModel & ManagedObjectContext within this subclass, or are these supposed to be configured within the AppDelegate (and if so, how do I go about refreshing the persistentStoreCoordinator to look at the new file - it seems that once that has read a persistentStore that I can't get it to read a new persistent store)?
Richard's example is an excellent example. I used it and the PragmaProg book on core data http://pragprog.com/book/mzcd2/core-data as a guide for creating my managed document module on github.
See: https://github.com/dtrotzjr/APManagedDocument
My code makes use of iOS 7 iCloud Core Data behavior which I cannot comment on publicly until the NDA is lifted. Feel free to ping me directly if you have any questions.
I've just posted a project based on Rick Warren's example: MultiDocumentPlusUUID. In his "Syncing Multiple Core Data Documents Using iCloud" post, Rick writes:
Another bug often shows up when I start trying to pass changes back and forth between devices that both have the same file open. The first sync always seems to work--and it seems to work pretty well as long as each subsequent sync is in the same direction.
MultiDocumentPlusUUID compiles and runs on iOS 7.1b4, and can ping-pong updates to a given document successfully.

Equivalent to R in iOS

In android we have the R class that stands for Resources, where we have references to all of our resources and we can easily access them in the code. Is there an equivalent in iOS? I have this doubt because, I want to be able to define multiple files with different values, for instance:
DefaultValuesForViewController1
DefaultValuesForViewController2
Besides creating plist, is there another way (faster and easier like R)?
There is no R class equivalent access method.
In Android, the R class represents access to resources that are consolidated into a native format. iPhone does not do this. Instead, resource files are just copied as is into the application bundle and must be found & opened as such.
You could create a class to store all of your data for the app. iOS generally likes the app to run lean and mean, so only storing your objects for as long as you need them, releasing them as soon as you are done with them. If you were to store everything globally, it would add some overhead, but assuming you don't have a ton of information, it shouldn't be an issue.
There is no equivalent for this in iOS apps. All you get is files that you can enumerate using standard file I/O.
However, you can emulate it partially. Here's a simple demo on GitHub
You can find that SwiftGen(e.g. Tuist used it) can be used as an alternative for autogenerated R.java file on Android
Two point
it is third party source
you have to manually run script after changing your resources