Skip to content

Commit dcddf15

Browse files
Merge pull request #1 from AlexTrotsenko/2020_04_noaudiostreamfix
Merge with latest master (as of 07.04.2020)
2 parents 74dbf9b + aa7dc58 commit dcddf15

File tree

18 files changed

+183
-46
lines changed

18 files changed

+183
-46
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## 0.3.0
2+
- Fix cancel() sometimes not working. (Thanks @strayerM and @PinkFloyded)
3+
- Geolocation support on API>=19. (Thanks @hkurokawa)
4+
5+
## 0.2.0
6+
- Experimental audio transcoding support. (Thanks @aaron112)
7+
- Fix transcode does not run on Huawei Ascend P7. (Thanks @spiritedRunning)
8+
- Fix race condition caused by not closing output before callback. (Thanks @ryanwilliams83)
9+
10+
## 0.1.10
11+
- `Future` support. (Thanks @MaiKambayashi)
12+
13+
## 0.1.X
14+
- Stability updates. (Thanks @ozyozyo)
15+
16+
## 0.1.0
17+
- First release.

README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ repositories {
6767
```
6868

6969
```groovy
70-
compile 'net.ypresto.androidtranscoder:android-transcoder:0.1.10'
70+
compile 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
7171
```
7272

7373
## Note (PLEASE READ FIRST)
@@ -78,6 +78,20 @@ Use [qtfaststart-java](https://github.com/ypresto/qtfaststart-java) to place moo
7878
- Android does not gurantees that all devices have bug-free codecs/accelerators for your codec parameters (especially, resolution). Refer [supported media formats](http://developer.android.com/guide/appendix/media-formats.html) for parameters guaranteed by [CTS](https://source.android.com/compatibility/cts-intro.html).
7979
- This library does not support video files recorded by other device like digital cameras, iOS (mov files, including non-baseline profile h.264), etc.
8080

81+
82+
## More information about internals
83+
84+
There is a blog post about this library written in Japanese.
85+
http://qiita.com/yuya_presto/items/d48e29c89109b746d000
86+
87+
While it is Japanese, diagrams would be useful for understanding internals of this library.
88+
89+
## References for Android Low-Level Media APIs
90+
91+
- http://bigflake.com/mediacodec/
92+
- https://github.com/google/grafika
93+
- https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright
94+
8195
## License
8296

8397
```
@@ -95,9 +109,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95109
See the License for the specific language governing permissions and
96110
limitations under the License.
97111
```
98-
99-
## References for Android Low-Level Media APIs
100-
101-
- http://bigflake.com/mediacodec/
102-
- https://github.com/google/grafika
103-
- https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright

build.gradle

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
buildscript {
44
repositories {
55
jcenter()
6+
maven {
7+
url 'https://maven.google.com/'
8+
name 'Google'
9+
}
610
}
711
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.1.2'
12+
classpath 'com.android.tools.build:gradle:2.3.3'
913

1014
// NOTE: Do not place your application dependencies here; they belong
1115
// in the individual module build.gradle files
@@ -15,5 +19,9 @@ buildscript {
1519
allprojects {
1620
repositories {
1721
jcenter()
22+
maven {
23+
url 'https://maven.google.com/'
24+
name 'Google'
25+
}
1826
}
1927
}

example/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
22

33
android {
44
compileSdkVersion 24
5-
buildToolsVersion "24.0.1"
5+
buildToolsVersion '25.0.0'
66

77
defaultConfig {
88
applicationId "net.ypresto.androidtranscoder.example"
@@ -21,4 +21,5 @@ android {
2121

2222
dependencies {
2323
compile project(':lib')
24+
compile 'com.android.support:support-core-utils:24.2.0'
2425
}

example/src/main/AndroidManifest.xml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
package="net.ypresto.androidtranscoder.example" >
3+
package="net.ypresto.androidtranscoder.example">
4+
5+
<uses-permission
6+
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
7+
android:maxSdkVersion="18" />
48

59
<application
610
android:allowBackup="true"
711
android:icon="@drawable/ic_launcher"
812
android:label="@string/app_name"
9-
android:theme="@style/AppTheme" >
13+
android:theme="@style/AppTheme">
1014
<activity
1115
android:name=".TranscoderActivity"
12-
android:label="@string/app_name" >
16+
android:label="@string/app_name">
1317
<intent-filter>
1418
<action android:name="android.intent.action.MAIN" />
1519

1620
<category android:name="android.intent.category.LAUNCHER" />
1721
</intent-filter>
1822
</activity>
23+
24+
<provider
25+
android:name="android.support.v4.content.FileProvider"
26+
android:authorities="net.ypresto.androidtranscoder.example.fileprovider"
27+
android:exported="false"
28+
android:grantUriPermissions="true">
29+
<meta-data
30+
android:name="android.support.FILE_PROVIDER_PATHS"
31+
android:resource="@xml/file_paths" />
32+
</provider>
1933
</application>
2034

2135
</manifest>

example/src/main/java/net/ypresto/androidtranscoder/example/TranscoderActivity.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.os.Bundle;
88
import android.os.ParcelFileDescriptor;
99
import android.os.SystemClock;
10+
import android.support.v4.content.FileProvider;
1011
import android.util.Log;
1112
import android.view.Menu;
1213
import android.view.MenuItem;
@@ -26,6 +27,7 @@
2627

2728
public class TranscoderActivity extends Activity {
2829
private static final String TAG = "TranscoderActivity";
30+
private static final String FILE_PROVIDER_AUTHORITY = "net.ypresto.androidtranscoder.example.fileprovider";
2931
private static final int REQUEST_CODE_PICK = 1;
3032
private static final int PROGRESS_BAR_MAX = 1000;
3133
private Future<Void> mFuture;
@@ -55,7 +57,10 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
5557
final File file;
5658
if (resultCode == RESULT_OK) {
5759
try {
58-
file = File.createTempFile("transcode_test", ".mp4", getExternalFilesDir(null));
60+
File outputDir = new File(getExternalFilesDir(null), "outputs");
61+
//noinspection ResultOfMethodCallIgnored
62+
outputDir.mkdir();
63+
file = File.createTempFile("transcode_test", ".mp4", outputDir);
5964
} catch (IOException e) {
6065
Log.e(TAG, "Failed to create temporary file.", e);
6166
Toast.makeText(this, "Failed to create temporary file.", Toast.LENGTH_LONG).show();
@@ -89,7 +94,10 @@ public void onTranscodeProgress(double progress) {
8994
public void onTranscodeCompleted() {
9095
Log.d(TAG, "transcoding took " + (SystemClock.uptimeMillis() - startTime) + "ms");
9196
onTranscodeFinished(true, "transcoded file placed on " + file, parcelFileDescriptor);
92-
startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file), "video/mp4"));
97+
Uri uri = FileProvider.getUriForFile(TranscoderActivity.this, FILE_PROVIDER_AUTHORITY, file);
98+
startActivity(new Intent(Intent.ACTION_VIEW)
99+
.setDataAndType(uri, "video/mp4")
100+
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION));
93101
}
94102

95103
@Override
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<paths>
3+
<external-path
4+
name="output_videos"
5+
path="Android/data/net.ypresto.androidtranscoder.example/files/outputs" />
6+
</paths>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Mon Mar 09 14:43:12 JST 2015
1+
#Thu Jun 08 12:40:11 IST 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

lib/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ apply plugin: 'bintray-release'
1212

1313
android {
1414
compileSdkVersion 24
15-
buildToolsVersion "24.0.1"
15+
buildToolsVersion '25.0.2'
1616

1717
defaultConfig {
1818
minSdkVersion 18
@@ -32,7 +32,7 @@ android {
3232
publish {
3333
groupId = 'net.ypresto.androidtranscoder'
3434
artifactId = 'android-transcoder'
35-
version = '0.1.10-SNAPSHOT'
35+
version = '0.3.0'
3636
licences = ['Apache-2.0']
3737
website = 'https://github.com/ypresto/android-transcoder'
3838
autoPublish = false
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.ypresto.androidtranscoder.utils;
2+
3+
import junit.framework.TestCase;
4+
5+
public class ISO6709LocationParserTest extends TestCase {
6+
public void testParse() {
7+
ISO6709LocationParser parser = new ISO6709LocationParser();
8+
assertEquals(new float[]{35.658632f, 139.745411f}, parser.parse("+35.658632+139.745411/"));
9+
assertEquals(new float[]{40.75f, -074.00f}, parser.parse("+40.75-074.00/"));
10+
// with Altitude
11+
assertEquals(new float[]{-90f, +0f}, parser.parse("-90+000+2800/"));
12+
assertEquals(new float[]{27.5916f, 086.5640f}, parser.parse("+27.5916+086.5640+8850/"));
13+
// ranged data
14+
assertEquals(new float[]{35.331f, 134.224f}, parser.parse("+35.331+134.224/+35.336+134.228/"));
15+
assertEquals(new float[]{35.331f, 134.224f}, parser.parse("+35.331+134.224/+35.336+134.228/+35.333+134.229/+35.333+134.227/"));
16+
}
17+
18+
public void testParseFailure() {
19+
ISO6709LocationParser parser = new ISO6709LocationParser();
20+
assertNull(parser.parse(null));
21+
assertNull(parser.parse(""));
22+
assertNull(parser.parse("35 deg 65' 86.32\" N, 139 deg 74' 54.11\" E"));
23+
assertNull(parser.parse("+35.658632"));
24+
assertNull(parser.parse("+35.658632-"));
25+
assertNull(parser.parse("40.75-074.00"));
26+
assertNull(parser.parse("+40.75-074.00.00"));
27+
}
28+
29+
private static void assertEquals(float[] expected, float[] actual) {
30+
assertEquals(expected.length, actual.length);
31+
for (int i = 0; i < expected.length; i++) {
32+
assertTrue(Float.compare(expected[i], actual[i]) == 0);
33+
}
34+
}
35+
}

lib/src/main/java/net/ypresto/androidtranscoder/MediaTranscoder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,20 @@ public void onTranscodeProgress(double progress) {
123123

124124
@Override
125125
public void onTranscodeCompleted() {
126-
listener.onTranscodeCompleted();
127126
closeStream();
127+
listener.onTranscodeCompleted();
128128
}
129129

130130
@Override
131131
public void onTranscodeCanceled() {
132-
listener.onTranscodeCanceled();
133132
closeStream();
133+
listener.onTranscodeCanceled();
134134
}
135135

136136
@Override
137137
public void onTranscodeFailed(Exception exception) {
138-
listener.onTranscodeFailed(exception);
139138
closeStream();
139+
listener.onTranscodeFailed(exception);
140140
}
141141

142142
private void closeStream() {

lib/src/main/java/net/ypresto/androidtranscoder/engine/AudioTrackTranscoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void setup() {
7979

8080
@Override
8181
public MediaFormat getDeterminedFormat() {
82-
return mInputFormat;
82+
return mActualOutputFormat;
8383
}
8484

8585
@Override

lib/src/main/java/net/ypresto/androidtranscoder/engine/MediaFormatValidator.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,8 @@
1818
import android.media.MediaFormat;
1919

2020
import net.ypresto.androidtranscoder.format.MediaFormatExtraConstants;
21-
import net.ypresto.androidtranscoder.utils.AvcCsdUtils;
22-
import net.ypresto.androidtranscoder.utils.AvcSpsUtils;
23-
24-
import java.nio.ByteBuffer;
2521

2622
class MediaFormatValidator {
27-
// Refer: http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles
28-
private static final byte PROFILE_IDC_BASELINE = 66;
2923

3024
public static void validateVideoOutputFormat(MediaFormat format) {
3125
String mime = format.getString(MediaFormat.KEY_MIME);
@@ -34,11 +28,6 @@ public static void validateVideoOutputFormat(MediaFormat format) {
3428
if (!MediaFormatExtraConstants.MIMETYPE_VIDEO_AVC.equals(mime)) {
3529
throw new InvalidOutputFormatException("Video codecs other than AVC is not supported, actual mime type: " + mime);
3630
}
37-
ByteBuffer spsBuffer = AvcCsdUtils.getSpsBuffer(format);
38-
byte profileIdc = AvcSpsUtils.getProfileIdc(spsBuffer);
39-
if (profileIdc != PROFILE_IDC_BASELINE) {
40-
throw new InvalidOutputFormatException("Non-baseline AVC video profile is not supported by Android OS, actual profile_idc: " + profileIdc);
41-
}
4231
}
4332

4433
public static void validateAudioOutputFormat(MediaFormat format) {

lib/src/main/java/net/ypresto/androidtranscoder/engine/MediaTranscoderEngine.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
import android.media.MediaFormat;
2020
import android.media.MediaMetadataRetriever;
2121
import android.media.MediaMuxer;
22+
import android.os.Build;
2223
import android.util.Log;
2324

25+
import net.ypresto.androidtranscoder.BuildConfig;
2426
import net.ypresto.androidtranscoder.format.MediaFormatStrategy;
27+
import net.ypresto.androidtranscoder.utils.ISO6709LocationParser;
2528
import net.ypresto.androidtranscoder.utils.MediaExtractorUtils;
2629

2730
import java.io.FileDescriptor;
@@ -137,9 +140,17 @@ private void setupMetadata() throws IOException {
137140
// skip
138141
}
139142

140-
// TODO: parse ISO 6709
141-
// String locationString = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION);
142-
// mMuxer.setLocation(Integer.getInteger(rotationString, 0));
143+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
144+
String locationString = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION);
145+
if (locationString != null) {
146+
float[] location = new ISO6709LocationParser().parse(locationString);
147+
if (location != null) {
148+
mMuxer.setLocation(location[0], location[1]);
149+
} else {
150+
Log.d(TAG, "Failed to parse the location metadata: " + locationString);
151+
}
152+
}
153+
}
143154

144155
try {
145156
mDurationUs = Long.parseLong(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) * 1000;
@@ -189,7 +200,7 @@ public void onDetermineOutputFormat() {
189200
mAudioTrackTranscoder.setup();
190201
}
191202

192-
private void runPipelines() {
203+
private void runPipelines() throws InterruptedException {
193204
long loopCount = 0;
194205
if (mDurationUs <= 0) {
195206
double progress = PROGRESS_UNKNOWN;
@@ -208,11 +219,7 @@ private void runPipelines() {
208219
if (mProgressCallback != null) mProgressCallback.onProgress(progress);
209220
}
210221
if (!stepped) {
211-
try {
212-
Thread.sleep(SLEEP_TO_WAIT_TRACK_TRANSCODERS);
213-
} catch (InterruptedException e) {
214-
// nothing to do
215-
}
222+
Thread.sleep(SLEEP_TO_WAIT_TRACK_TRANSCODERS);
216223
}
217224
}
218225
}

lib/src/main/java/net/ypresto/androidtranscoder/format/MediaFormatStrategyPresets.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
package net.ypresto.androidtranscoder.format;
1717

1818
public class MediaFormatStrategyPresets {
19+
public static final int AUDIO_BITRATE_AS_IS = -1;
20+
public static final int AUDIO_CHANNELS_AS_IS = -1;
21+
1922
/**
2023
* @deprecated Use {@link #createExportPreset960x540Strategy()}.
2124
*/
@@ -45,7 +48,7 @@ public static MediaFormatStrategy createAndroid720pStrategy(int bitrate) {
4548
/**
4649
* Preset based on Nexus 4 camera recording with 720p quality.
4750
* This preset is ensured to work on any Android &gt;=4.3 devices by Android CTS (if codec is available).
48-
* <p/>
51+
* <br>
4952
* Note: audio transcoding is experimental feature.
5053
*
5154
* @param bitrate Preferred bitrate for video encoding.

0 commit comments

Comments
 (0)