Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIMOB-26599 Optionally disable video compression when importing video #10492

Merged
merged 21 commits into from
May 9, 2019

Conversation

rlustemberg
Copy link
Contributor

JIRA: https://jira.appcelerator.org/browse/TIMOB-26599

Optionally disable video compression when importing video

@build
Copy link
Contributor

build commented Nov 27, 2018

Fails
🚫

🔬 There are library changes, but no changes to the unit tests. That's OK as long as you're refactoring existing code, but will require an admin to merge this PR. Please see README.md#unit-tests for docs on unit testing.

🚫 Tests have failed, see below for more information.
Messages
📖

💾 Here's the generated SDK zipfile.

📖 🎉 Another contribution from our awesome community member, rlustemberg! Thanks again for helping us make Titanium SDK better. 👍
📖 ❌ 91 tests have failed There are 91 tests failing and 446 skipped out of 3582 total tests.

Tests:

Classname Name Time Error
android.emulator.Titanium.UI.ImageView should handle absolute-looking paths by resolving relative to resource dir 5.007 timeout of 5000ms exceeded
android.emulator.Titanium.UI.ImageView should handle file URLs from applicationDataDirectory - TIMOB-18262 5.006 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Label maxLines-newline 5.027 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23225 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #10 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #9 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #8 5.004 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #7 5.013 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #6 5.009 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #5 5.007 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #4 5.01 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #3 5.007 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #2 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout TIMOB-23372 #1 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout layoutWithSIZE_and_fixed 5.007 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout fourPins 5.034 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout twoPins 5.01 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout scrollViewWithLargeVerticalLayoutChild 5.005 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout scrollViewWithTop 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout scrollViewWithSIZE 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout unitMeasurements 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout sizeFillConflict 5.036 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout fillInVerticalLayout 5.032 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout zIndexMultiple 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout heightPrecedence 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout widthPrecedence 5.003 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedBottom 5.015 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedHeight 5.013 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedRight 5.006 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedCenter 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedLeft 5.017 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout undefinedWidth 4.999 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewError 5.039 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewWidth 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewCenter 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewTop 5.013 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewLeft 5.003 timeout of 5000ms exceeded
android.emulator.Titanium.UI.Layout viewSizeAndRectPx 4.999 timeout of 5000ms exceeded
android.emulator.Titanium.UI.ListView listView with Ti.UI.Android.CardView 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView .refreshControl (Basic) 60.001 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView TIMOB-24019 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView deleteSectionAt 60.001 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView replaceSectionAt 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView insertSectionAt 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView appendSection 60.001 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView Custom template 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView headerView 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.ListView section header & footer 60 timeout of 60000ms exceeded
android.emulator.Titanium.UI.MaskedImage mask-tint 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.NavigationWindow #popToRootWindow 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.NavigationWindow #openWindow, #closeWindow 9.999 timeout of 10000ms exceeded
android.emulator.Titanium.UI.NavigationWindow basic open/close navigation 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.NavigationWindow open/close should open/close the window 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Window .navigationWindow 10.002 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker Selected index persistance 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker DatePicker postlayout event 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker DatePicker maxDate 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker DatePicker minDate 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker change event 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker.removeRow 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker.add (PickerRow) 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker.add(multiple PickerColumn) 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker.add(PickerColumn) 10 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker PlainPicker 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker TimePicker 10.001 timeout of 10000ms exceeded
android.emulator.Titanium.UI.Picker DatePicker 10.003 timeout of 10000ms exceeded
android.emulator.Titanium.UI.ScrollableView clipViews 5 timeout of 5000ms exceeded
android.emulator.Titanium.UI.ScrollView Ti.UI.SIZE 20.001 timeout of 20000ms exceeded
android.emulator.Titanium.UI.TabbedBar Index update - before window.open() 5.009 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Labels update - before window.open() 5.005 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Index - getter read 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Index - setter change 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Index - direct change 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Labels update 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Labels from BarItemType 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabbedBar Labels from Strings 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TabGroup add Map.View to TabGroup 15.54 timeout of 10000ms exceeded
android.emulator.Titanium.UI.TableView SearchView persistence 2.001 timeout of 2000ms exceeded
android.emulator.Titanium.UI.TableView Add and remove headerView/footerView 5.007 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TableView insertSectionBefore 5.004 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TableView insertSectionAfter 5.002 timeout of 5000ms exceeded
android.emulator.Titanium.UI.TextArea textArea in tabGroup 7.505 timeout of 7500ms exceeded
android.emulator.Titanium.UI.TextField focus-win-open 5.001 timeout of 5000ms exceeded
android.emulator.Titanium.UI.WebView ignoreSslError 30.007 timeout of 30000ms exceeded
android.emulator.Titanium.UI.WebView sslerror 30.009 timeout of 30000ms exceeded
android.emulator.Titanium.UI.WebView should handle file URLs with spaces in path - TIMOB-18765 30.003 timeout of 30000ms exceeded
android.emulator.Titanium.UI.WebView #evalJS(string, function) - async variant 30.001 timeout of 30000ms exceeded
android.emulator.Titanium.UI.WebView .zoomLevel 10.014 timeout of 10000ms exceeded
android.emulator.Titanium.UI.WebView data 30.009 timeout of 30000ms exceeded
android.emulator.Titanium.UI.WebView url 30.002 timeout of 30000ms exceeded
android.emulator.Titanium.Utils #base64encode(Ti.Blob#TYPE_DATA from Ti.UI.View.toImage() async) 5.009 timeout of 5000ms exceeded

Generated by 🚫 dangerJS against 3bb2fcd

@build build added this to the 8.0.0 milestone Dec 25, 2018
@build build requested a review from a team December 25, 2018 21:31
@vijaysingh-axway vijaysingh-axway modified the milestones: 8.0.0, 8.1.0 Jan 4, 2019
Copy link
Contributor

@janvennemann janvennemann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Please check the linting issues and document the new option.

cc @garymathews @jquick-axway Do we need parity with Android for this? Is there an equivalent option?

@@ -665,7 +665,7 @@ - (void)requestAudioRecorderPermissions:(id)args
TiThreadPerformOnMainThread(^() {
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
KrollEvent *invocationEvent = [[KrollEvent alloc] initWithCallback:callback
eventObject:[TiUtils dictionaryWithCode:(granted ? 0 : 1) message:nil]
eventObject:[TiUtils dictionaryWithCode:(granted ? 0 : 1)message:nil]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please re-add the whitespace here and in the other places.

Tip: Run grunt format:ios to let clang-format fix linting issues for you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was using clang-format. Somehow it seems to have done the deed with different settings and produced a different result.

@@ -1704,6 +1704,12 @@ - (void)showPicker:(NSDictionary *)args isCamera:(BOOL)isCamera
[self displayCamera:picker];
}
} else {
if ([TiUtils isIOS11OrGreater]) {
BOOL disableVideoCompression = [TiUtils boolValue:@"disableVideoCompression" properties:args def:NO];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@jquick-axway
Copy link
Contributor

I'm not sure if naming the property disableVideoCompression is the right name.

You're using the AVAssetExportPresetPassthrough constant which tells iOS to return the video as-is, without reformatting the video. I suppose using the camera's default video format. But the video taken has to be recorded to a format of some kind (h.264?) and odds are it's a compressed format. It might happen to be a lossless compression, but it's still technically a compressed format. (Storing the video as a series of uncompressed bitmaps would be crazy.)

We currently offer a "videoQuality" property which can be set to low/medium/high. So, I'm guessing setting it to HIGH will still have iOS reformat the video from "h.264" to maybe a quicktime "mov" format? Is this the issue you're dealing with? Is it more of an issue with the returned video format?
https://docs.appcelerator.com/platform/latest/#!/api/CameraOptionsType-property-videoQuality

If you can tell me your use-case, then that would help. If you are after a "h.264" video format, then the issue here is we can't provide that on other platforms. The video format recorded will vary wildly on different Android devices.

In any case, as it stands now, using the AVAssetExportPresetPassthrough constant returns the "native" video format the iOS device records to. So, perhaps the appropriate thing to do is have a QUALITY_NATIVE media constant? Or have a useNativeFormat boolean property?

@rlustemberg
Copy link
Contributor Author

I'm not sure if naming the property disableVideoCompression is the right name.

You're using the AVAssetExportPresetPassthrough constant which tells iOS to return the video as-is, without reformatting the video. I suppose using the camera's default video format. But the video taken has to be recorded to a format of some kind (h.264?) and odds are it's a compressed format. It might happen to be a lossless compression, but it's still technically a compressed format. (Storing the video as a series of uncompressed bitmaps would be crazy.)

We currently offer a "videoQuality" property which can be set to low/medium/high. So, I'm guessing setting it to HIGH will still have iOS reformat the video from "h.264" to maybe a quicktime "mov" format? Is this the issue you're dealing with? Is it more of an issue with the returned video format?
https://docs.appcelerator.com/platform/latest/#!/api/CameraOptionsType-property-videoQuality

If you can tell me your use-case, then that would help. If you are after a "h.264" video format, then the issue here is we can't provide that on other platforms. The video format recorded will vary wildly on different Android devices.

In any case, as it stands now, using the AVAssetExportPresetPassthrough constant returns the "native" video format the iOS device records to. So, perhaps the appropriate thing to do is have a QUALITY_NATIVE media constant? Or have a useNativeFormat boolean property?

Hi Joshua. I was actually thinking on exposing the video quality property and constants. The code from the PR is a quick fix for my usage case. The current defaults cause bad UX when importing long videos from the gallery. It can take a long time to re-encode a 5 minutes video. On top of that, in the app I'm working on, I will later re-encode the video again using SDAVAssetExportSession libraries, to get a more fine tuned result. What shall we do, change the property name to useNativeFormat or directly expose the constants? @janvennemann @jquick-axway

@jquick-axway
Copy link
Contributor

@rlustemberg , oh I see. This was a performance issue with it being re-encoded. Gotcha. (Sorry for not not fully understanding the issue.)

I was just looking at this from a documentation and cross-platform perspective.

Android doesn't re-encode videos selected from the gallery. So, this should never be an issue on Android. This sounds like an iOS only issue.

How about we rename disableVideoCompression to allowTranscoding?

The word "transcoding" might better describe what's going on iOS. It's true by default. So in your case, you want to disable it and flip the code's logic if you don't mind. And the word "allow" fits with the other property settings too.

@janvennemann, what do you think?

@rlustemberg
Copy link
Contributor Author

Done!

@build build added the docs label Jan 15, 2019
Copy link
Contributor

@vijaysingh-axway vijaysingh-axway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rlustemberg Thanks for PR! I have added few review comments.

@@ -1704,6 +1704,12 @@ - (void)showPicker:(NSDictionary *)args isCamera:(BOOL)isCamera
[self displayCamera:picker];
}
} else {
if ([TiUtils isIOS11OrGreater]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use [TiUtils isIOSVersionOrGreater:@"11.0"] instead of [TiUtils isIOS11OrGreater] because later one is deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

type: Boolean
default: true
platforms: [iphone, ipad]
since: "8.1.0"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add minimum iOS version in document as well. Because this property is only available in iOS 11.0+.
e.g.
osver: {ios: {min: "11.0"}}

Copy link
Contributor Author

@rlustemberg rlustemberg Jan 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@@ -1704,6 +1704,12 @@ - (void)showPicker:(NSDictionary *)args isCamera:(BOOL)isCamera
[self displayCamera:picker];
}
} else {
if ([TiUtils isIOS11OrGreater]) {
BOOL allowTranscoding = [TiUtils boolValue:@"allowTranscoding" properties:args def:YES];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it better if we expose it as a string/constant property and expose other constants as well which is available ? e.g Constants -
AVAssetExportPresetAppleM4A, AVAssetExportPresetHEVC3840x2160, AVAssetExportPresetHEVC1920x1080 etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed. I've made a quick and dirty solution based on my use case, but I think it's better to provide full control. It's up to you guys, if you want that and the choice using strings or exporting the enum constants

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those other constants tell iOS what to transcode the video formats to.
We can do this 1 of 2 ways.

(1) Keep the "allowTranscoding" property and add a "transcodeFormat" type later which tells the system which format to transcode to if "allowTranscoding" is true.

(2) Get rid of the "allowTranscoding" property and provide a "transcodeFormat" type instead which when set null (or to a NONE type?), will handle it from there.

I think the only things that worries me here is that format types available will vary between iOS versions... or perhaps worse, by device?

Hypothetically, if we were to support this on any other platform (Android and Windows), then you would need to query the system for what formats are available. You can't hard-code it to a format and expect it to magically work. For example, Android device manufacturers may not support some of Google's documented formats in order to lower the cost of the device since there is licensing/royalties involved (I've seen this with low-cost tablets in the past). And Windows N-edition and K-edition don't include any licensed formats by default.

Because of the above, I prefer to keep it simple for now.
Besides, wouldn't most devs want the original video format anyways?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with solution 1. Let's have it simple for now as it is. We can add "transcodeFormat" later.
@rlustemberg If you can resolve other two minor issues-

  1. add minimum iOS version in document
  2. Use [TiUtils isIOSVersionOrGreater:@"11.0"] instead of [TiUtils isIOS11OrGreater].
    we will be good to go. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Contributor

@vijaysingh-axway vijaysingh-axway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR passed.

@ssjsamir ssjsamir self-requested a review February 27, 2019 13:14
Copy link
Contributor

@ssjsamir ssjsamir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FR Passed: When 'allowTranscoding' is set to 'false' the newly formatted video is returned quicker than if 'allowTranscoding' was set to 'true'. Tested using the information found in: https://jira.appcelerator.org/browse/TIMOB-26599.

Ti.Media.openPhotoGallery({
allowTranscoding: false,
mediaTypes: [Ti.Media.MEDIA_TYPE_VIDEO],
success: function(e) {
// Got it.
},
});

Test Environment

iPhone 6S plus (12.1)
APPC CLI: 7.0.10-17
Operating System Name: Mac OS Mojave
Operating System Version: 10.14.2
Node.js Version: 8.9.1
Xcode 10.1

@build
Copy link
Contributor

build commented Apr 17, 2019

Messages
📖

💾 Here's the generated SDK zipfile.

📖 🎉 Another contribution from our awesome community member, rlustemberg! Thanks again for helping us make Titanium SDK better. 👍
📖

✅ All tests are passing
Nice one! All 3727 tests are passing.
(There are 466 tests skipped)

Generated by 🚫 dangerJS against 97e365e

@ssjsamir ssjsamir merged commit fdadb3d into tidev:master May 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants