When using AVPlayerItemLegibleOutput to obtain a sequence of subtitles from a video stream the results are returned as NSAttributedStrings through AVPlayerItemLegibleOutputPushDelegate method:
func legibleOutput(
_: AVPlayerItemLegibleOutput,
didOutputAttributedStrings strings: [NSAttributedString],
nativeSampleBuffers _: [Any],
forItemTime itemTime: CMTime
)
Inspecting the string's attributes I see that rather than NSAttributedString.Key values such as NSAttributedString.Key.font, NSAttributedString.Key.foregroundColor we have Core Media attributes such as CMFontFamilyName and CMForegroundColorARGB.
As these attributes reflect the user's device accessibility settings for subtitles and closed-captions they should not be ignored. Unfortunately UILabel cannot render them.
So my question is what is the correct approach to rendering these strings (when automatic player caption rendering isn't suitable)?
Related
I am using Honeywell Captuvo Device and it's SDK for scanning barcode with iPod. Unfortunately there is no delegate methods which can give a Type of Barcode Scanned. There are two delegate method which gives you string value of barcode and NSData from the barcode scanned.
//Raw Data by delegate method.
func decoderRawDataReceived(data: NSData!) {
}
//String return by delegate method.
func decoderDataReceived(data: String!) {
}
As i am getting two type of data from scanning a barcode. I have been searching for a solution by which i can get barcode type of scanned data.
Is there a way i can get Barcode type from NSData or String type?
I've been looking for an answer to this as well, and came up with a roundabout way to do it since the SDK doesn't have that ability.
In the Captuvo Sled User's Guide, it outlines ways to configure the scanner separately from the SDK. In the Data Editing section, it outlines some configuration options that you may be interested in. You can add a prefix/suffix to different barcode symbologies.
Perhaps easier, is, in the Data Formatting section, it mentions the ability to:
Insert symbology name
B3
Insert the name of the bar code’s symbology in the output message,
without moving the cursor. Only symbologies with a Honeywell ID are
included (see Symbology Chart on page A-1). Refer to the ASCII
Conversion Chart (Code Page 1252), page A-4 for decimal, hex and
character codes.
So, configure the scanner first, and then you'll be able to parse the
symbology.
I'm working an iOS application that uses an AVPlayer to play songs represented by AVPlayerItems.
I've tried setting the nowPlayingInfo property of MPNowPlayingInfoCenter.defaultCenter() but it appears that the info gets immediately overwritten by the AVPlayer since it needs to update other info like elapsedTime and playbackDuration.
Even immediately after the program executes
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPMediaItemPropertyTitle] = "Title"
The printout of MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo is
Info: ["MPNowPlayingInfoPropertyElapsedPlaybackTime": 34.89555007300078, "AVNowPlayingInfoControllerIdentifierKey": <__NSConcreteUUID 0x13778e9b0> 9141DD1C-FD09-4210-B3C7-B948522E3AF6, "playbackDuration": 198.2516666666667, "MPNowPlayingInfoPropertyPlaybackRate": 1]
What am I doing wrong? Is it possible to store additional metadata like title/album name in an AVPlayerItem so it gets displayed on the info center?
Also, what is AVNowPlayingInfoControllerIdentifierKey? There do not seem to be any classes named AVNowPlayingInfoController.
The problem is that this line does nothing:
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo?[MPMediaItemPropertyTitle] =
"Title"
Even if that line actually did anything, you would be fetching a copy of the nowPlayingInfo as a separate dictionary and then writing into that separate dictionary. You would not be writing into the actual now playing info, which is what you want to do.
The correct approach is to form a dictionary and then set MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo to that dictionary.
For example:
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo =
[MPMediaItemPropertyTitle : "Title"]
(Of course the dictionary can have more entries.)
The documentation for kCTUnderlineStyleAttributeName relays the following:
kCTUnderlineStyleAttributeName
The style of underlining, to be applied at render time, for the text to which this attribute applies. Value must be a CFNumber object. Default is kCTUnderlineStyleNone. Set a value of something other than kCTUnderlineStyleNone to draw an underline. In addition, the constants listed in CTUnderlineStyleModifiers can be used to modify the look of the underline. The underline color is determined by the text's foreground color.
The signature for the setAttributes function is as follows:
func setAttributes(attrs: [NSObject : AnyObject]?, range: NSRange)
The issue that I'm having is that the documentation seems to allude to the fact that CTUnderlineStyle.Single can (and should, in Swift) be used as a value for the kCTUnderlineStyleAttributeName key. However, the former is a struct, and as a result does not conform to the AnyObject protocol required by the dictionaries value type.
Any ideas?
I spend quite a few time on this.
The value needs to confront the AnyObject protocol.
Instead of using CTUnderlineStyle.Single use NSNumber like this:
NSNumber(int: CTUnderlineStyle.Single.rawValue)
Example:
attributedString.addAttribute(kCTUnderlineStyleAttributeName, value:NSNumber(int: CTUnderlineStyle.Single.rawValue), range:NSRange(location:0,length:attributedString.length));
in swift 3 worked for me this code
let attributes:[AnyHashable : Any] = [kCTUnderlineStyleAttributeName as AnyHashable:NSNumber(value:CTUnderlineStyle.single.rawValue)]
Is there a way to get raw data of image from UIPasteboard instead of UIImage if it's copied by another app such as photos or mobile safari?
I'm currently facing wired differences between IOS 6.0 and IOS 6.1(7.0 also)
In IOS 6.0, UIPasteboard's item of the copied image by photos or mobile safari contains raw data of the image.
But In IOS 6.1 and above, it contains UIImage instead of raw data.
In IOS 6.0, copied item of UIPasteboard is below
Printing description of array:
<__NSArrayM 0x8a804c0>(
{
"com.compuserve.gif" = <47494638 39614002 ...... 3b3a2000 3b>;
"public.url" = "url of the image....";
}
)
In IOS 6.1 and above, it contains UIImage instead of raw data.
Printing description of array:
<__NSArrayM 0xa25b7b0>(
{
"com.compuserve.gif" = "<UIImage: 0x9429570>";
"public.url" = "url of the image...";
}
)
If that image format is PNG or JPEG, it's not that bad.
(I still have to compress again if it's JEPG though.)
But when I try to paste animated gif image, it becomes more complicated.
I don't know even it's passible to create animated gif image from normal UIImage.
I can download again from original url, but downloading data that I already have seems not good solution I think.
And also, if it's copied from photos app, there's no such url. (there's some mysterious uri named "com.apple.mobileslideshow.asset-object-id-uri" that is undocumented instead of url)
There seems a workaround, because when I try to do exactly same action between photos and email app, It works properly
Any suggestions?
Well now, I figured it out myself.
You can simply get raw (binary)data of the image form general pasteboard by sending
dataForPasteboardType:(NSSting*)PasteboardType message to general pasteboard, if it's copied from Apple's built-in Mobile Safari or Photos App. (#"com.compuserve.gif" for the pasteboard type in my case)
I myself feel a bit foolish for not having checked all the passible methods sooner. :(
My confusion comes from items property of the UIPasteboard.
I thought that items are containing all of data of current pasteboard. So I try to save that array from pasteboard and want to use it later, but I were totally wrong.
As documented in UIPasteboard Class Reference, the items property contains dictionary with key being the representation type and the "value" the object associated with that type.
At this point of time, The "value" refers really "value" of the representation, not the data of that type. This meaning of the "value" is the same as the value of thesetValue: forPasteboardType: method.
On the other words, you cannot retrieve raw(binary) data of the image from items property, even if you set the image to the pasteboard by sending setData: forPasteboardType: message.(I tested it on IOS 7)
In addition, raw data of the image from items property in IOS 6.0 seems a bug of that OS version. (This may not true, it's just my opinion)
You can get NSData from UIPasteboard if you specify right PasteboardType:
NSData* pasteData = [[UIPasteboard generalPasteboard] dataForPasteboardType:(NSString*)kUTTypeJPEG];
Do not forget to import
<MobileCoreServices/MobileCoreServices.h>
The UIPasteBoard will contain whatever is placed in it. It's up to the app that is copying to the paste board to put the contents in the proper format. The app can place items as raw binary data or as objects such as UIImage in the paste board.
If you're getting something different between iOS versions, you're probably using different versions of the app or it's simply copying things differently.
You're right that you can't represent an animated GIF in a UIImage because a UIImage only contains a single image. Perhaps the app is just copying the first frame's bitmap data in that case?
You can convert a UIImage to raw JPEG data using UIImageJPEGRepresentation.
I am using AVFoundation to capture still images from camera (capturing still images and not video frame) using captureStillImageAsynchronouslyFromConnection. This gives to me a buffer of type CMSSampleBuffer, which I am calling imageDataSampleBuffer.
As far as I have understood, this buffer can contain any type of data related to media, and the type of data is determined when I am configuring the output settings.
for output settings, I make a dictionary with value: AVVideoCodecJPEG for key: AVVideoCOdecKey.
There is no other codec option. But when I read the AVFoundation Programming Guide>Media Capture, I can see that 420f, 420v, BGRA, jpeg are the available encoded formats supported for iPhone 3gs (which i am using)
I want to get the yuv420 (i.e. 420v) formatted image data into the imageSampleBuffer. Is that possible?
if I print the availableImageDataCodecTypes, I get only JPEG
if I print availableImageDataCVPixelFormatTypes, I get three numbers 875704422, 875704438, 1111970369.
Is it possible that these three numbers map to 420f, 420v, BGRA?
If yes, which key should I modify in my output settings?
I tried putting the value: [NSNumber numberWithInt:875704438] for key: (id)kCVPixelBufferPixelFormatTypeKey.
Would it work?
If yes, how do I extract this data from the imageSampleBuffer?
Also, In which format is UIImage stored? Can it be any format? Is it just NSData with some extra info which makes it interpreted as an image?
I have been trying to use this method :
Raw image data from camera like "645 PRO"
I am saving the data using writeToFile and I have been trying to open it using irfan view.
But I am unable to verify whether or not the saved file is in yuv format ot not because irfan view gives error that it is unable to read the headers.