react-native-video-trim 1.0.24 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -9
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/videotrim/VideoTrimModule.java +191 -63
- package/android/src/main/java/com/videotrim/enums/ErrorCode.java +11 -0
- package/android/src/main/java/com/videotrim/interfaces/VideoTrimListener.java +6 -1
- package/android/src/main/java/com/videotrim/utils/MediaMetadataUtil.java +75 -0
- package/android/src/main/java/com/videotrim/utils/StorageUtil.java +2 -2
- package/android/src/main/java/com/videotrim/utils/VideoTrimmerUtil.java +36 -8
- package/android/src/main/java/com/videotrim/widgets/VideoTrimmerView.java +588 -308
- package/android/src/main/res/drawable/airpodsmax.xml +19 -0
- package/android/src/main/res/drawable/chevron_compact_left.xml +15 -0
- package/android/src/main/res/drawable/chevron_compact_right.xml +15 -0
- package/android/src/main/res/drawable/chevron_right_with_bg.xml +13 -0
- package/android/src/main/res/drawable/exclamationmark_triangle_fill.xml +15 -0
- package/android/src/main/res/drawable/pause_fill.xml +15 -0
- package/android/src/main/res/drawable/play_fill.xml +15 -0
- package/android/src/main/res/drawable/rounded_progress_indicator.xml +16 -0
- package/android/src/main/res/drawable/rounded_yellow_left_background.xml +8 -0
- package/android/src/main/res/drawable/rounded_yellow_right_background.xml +8 -0
- package/android/src/main/res/drawable/thumb_container_bg.xml +8 -0
- package/android/src/main/res/drawable/yellow_border.xml +9 -0
- package/android/src/main/res/layout/video_trimmer_view.xml +194 -75
- package/android/src/main/res/values/colors.xml +15 -13
- package/android/src/main/res/xml/file_paths.xml +5 -0
- package/ios/AssetLoader.swift +99 -0
- package/ios/ErrorCode.swift +16 -0
- package/ios/VideoTrim.mm +4 -2
- package/ios/VideoTrim.swift +405 -168
- package/ios/VideoTrimmer.swift +16 -10
- package/ios/VideoTrimmerViewController.swift +79 -13
- package/lib/commonjs/index.js +20 -57
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +19 -57
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/index.d.ts +47 -9
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +56 -66
- package/android/src/main/java/com/videotrim/adapters/VideoTrimmerAdapter.java +0 -54
- package/android/src/main/java/com/videotrim/widgets/RangeSeekBarView.java +0 -534
- package/android/src/main/java/com/videotrim/widgets/SpacesItemDecoration2.java +0 -33
- package/android/src/main/java/com/videotrim/widgets/ZVideoView.java +0 -48
- package/android/src/main/java/iknow/android/utils/BuildConfig.java +0 -18
- package/android/src/main/java/iknow/android/utils/DateUtil.java +0 -64
- package/android/src/main/res/drawable/ic_video_pause_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_play_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_thumb_handle.png +0 -0
- package/android/src/main/res/drawable/icon_seek_bar.png +0 -0
- package/android/src/main/res/layout/video_thumb_item_layout.xml +0 -16
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="165.48dp"
|
|
3
|
+
android:height="177.56dp"
|
|
4
|
+
android:viewportWidth="165.48"
|
|
5
|
+
android:viewportHeight="177.56">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h165.48v177.56h-165.48z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M5.3,102.25L11.93,102.25L11.93,85.75L5.3,85.75ZM42.93,177.56C52.3,177.56 56.8,168.88 51.61,159.69L20.93,105.25C18.55,101 14.86,99.06 10.36,99.06C2.68,99.06 -1.01,105.25 0.24,112.69C3.05,123.94 10.86,140.88 19.05,153.75C29.61,171.38 35.99,177.56 42.93,177.56ZM160.18,102.25L160.18,85.75L153.55,85.75L153.55,102.25ZM122.55,177.56C129.49,177.56 135.86,171.38 146.43,153.75C154.61,140.88 162.43,123.94 165.24,112.69C166.49,105.25 162.8,99.06 155.11,99.06C150.61,99.06 146.93,101 144.55,105.25L113.86,159.69C108.68,168.88 113.18,177.56 122.55,177.56ZM2.68,84.88C2.68,88.31 4.93,90.56 8.43,90.56C11.86,90.56 14.05,88.31 14.05,84.88C14.36,41.31 40.68,13.38 82.74,13.38C124.8,13.38 151.11,41.31 151.43,84.88C151.43,88.31 153.61,90.56 157.05,90.56C160.55,90.56 162.8,88.31 162.8,84.88C162.8,35.56 132.24,1.94 82.74,1.94C33.3,1.94 2.68,35.56 2.68,84.88Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="1"/>
|
|
15
|
+
<path
|
|
16
|
+
android:pathData="M65.3,161.75C70.49,158.81 71.86,152.38 68.61,146.63L41.99,99.56C38.68,93.75 32.55,91.75 27.36,94.69C24.3,96.44 23.61,99.19 25.24,102.06L57.86,159.81C59.49,162.75 62.3,163.5 65.3,161.75ZM100.18,161.75C103.18,163.5 105.99,162.75 107.61,159.81L140.24,102.06C141.86,99.19 141.18,96.44 138.11,94.69C132.93,91.75 126.8,93.75 123.49,99.56L96.86,146.63C93.61,152.38 94.99,158.81 100.18,161.75ZM35.74,40.69C48.74,33.56 64.43,29.81 82.74,29.81C101.05,29.81 116.74,33.56 129.74,40.69C119.3,27.81 104.05,20.81 82.74,20.81C61.43,20.81 46.18,27.81 35.74,40.69Z"
|
|
17
|
+
android:fillColor="#ffffff"
|
|
18
|
+
android:fillAlpha="0.5"/>
|
|
19
|
+
</vector>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="14.531dp"
|
|
3
|
+
android:height="53.086dp"
|
|
4
|
+
android:viewportWidth="14.531"
|
|
5
|
+
android:viewportHeight="53.086">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h14.531v53.086h-14.531z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M9.398,51.328C9.797,52.336 10.664,52.945 11.578,52.945C13.055,52.945 14.18,51.844 14.18,50.367C14.18,49.594 13.758,48.609 13.523,47.953L4.289,24.703L4.289,28.219L13.523,4.969C13.758,4.313 14.18,3.305 14.18,2.578C14.18,1.102 13.055,0 11.578,0C10.664,0 9.797,0.609 9.398,1.594L1.008,22.758C0.539,23.906 0,25.359 0,26.461C0,27.586 0.539,28.992 1.008,30.164Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="0.85"/>
|
|
15
|
+
</vector>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="14.531dp"
|
|
3
|
+
android:height="53.086dp"
|
|
4
|
+
android:viewportWidth="14.531"
|
|
5
|
+
android:viewportHeight="53.086">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h14.531v53.086h-14.531z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M4.781,51.328L13.172,30.164C13.641,28.992 14.18,27.586 14.18,26.461C14.18,25.359 13.641,23.906 13.172,22.758L4.781,1.594C4.383,0.609 3.516,0 2.602,0C1.125,0 0,1.102 0,2.578C0,3.305 0.398,4.313 0.656,4.969L9.867,28.219L9.867,24.703L0.656,47.953C0.398,48.609 0,49.594 0,50.367C0,51.844 1.125,52.945 2.602,52.945C3.516,52.945 4.383,52.336 4.781,51.328Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="0.85"/>
|
|
15
|
+
</vector>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<item android:drawable="@drawable/rounded_yellow_right_background"/>
|
|
3
|
+
<item>
|
|
4
|
+
<inset
|
|
5
|
+
android:insetLeft="8dp"
|
|
6
|
+
android:insetTop="8dp"
|
|
7
|
+
android:insetRight="8dp"
|
|
8
|
+
android:insetBottom="8dp"
|
|
9
|
+
android:drawable="@drawable/chevron_compact_right">
|
|
10
|
+
</inset>
|
|
11
|
+
</item>
|
|
12
|
+
</layer-list>
|
|
13
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="31.898dp"
|
|
3
|
+
android:height="28.887dp"
|
|
4
|
+
android:viewportWidth="31.898"
|
|
5
|
+
android:viewportHeight="28.887">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h31.898v28.887h-31.898z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M19.113,1.945L30.961,22.664C31.348,23.332 31.547,24.059 31.547,24.762C31.547,26.93 30.07,28.641 27.621,28.641L3.914,28.641C1.477,28.641 0,26.93 0,24.762C0,24.059 0.188,23.344 0.586,22.664L12.434,1.945C13.172,0.645 14.461,0 15.773,0C17.074,0 18.375,0.645 19.113,1.945ZM14.238,22.02C14.238,22.828 14.941,23.496 15.773,23.496C16.594,23.496 17.309,22.84 17.309,22.02C17.309,21.188 16.605,20.531 15.773,20.531C14.93,20.531 14.238,21.199 14.238,22.02ZM14.519,9.258L14.707,17.508C14.719,18.211 15.094,18.609 15.773,18.609C16.418,18.609 16.805,18.223 16.816,17.508L17.004,9.27C17.016,8.566 16.488,8.051 15.762,8.051C15.023,8.051 14.508,8.555 14.519,9.258Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="1"/>
|
|
15
|
+
</vector>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="35.953dp"
|
|
3
|
+
android:height="48.586dp"
|
|
4
|
+
android:viewportWidth="35.953"
|
|
5
|
+
android:viewportHeight="48.586">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h35.953v48.586h-35.953z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M3.75,48.563L10.5,48.563C13.008,48.563 14.25,47.32 14.25,44.813L14.25,3.75C14.25,1.172 13.008,0 10.5,0L3.75,0C1.242,0 0,1.266 0,3.75L0,44.813C0,47.32 1.242,48.563 3.75,48.563ZM25.102,48.563L31.852,48.563C34.359,48.563 35.602,47.32 35.602,44.813L35.602,3.75C35.602,1.172 34.359,0 31.852,0L25.102,0C22.594,0 21.352,1.266 21.352,3.75L21.352,44.813C21.352,47.32 22.594,48.563 25.102,48.563Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="1"/>
|
|
15
|
+
</vector>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="51.82dp"
|
|
3
|
+
android:height="50.977dp"
|
|
4
|
+
android:viewportWidth="51.82"
|
|
5
|
+
android:viewportHeight="50.977">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FF000000"
|
|
8
|
+
android:pathData="M0,0h51.82v50.977h-51.82z"
|
|
9
|
+
android:strokeAlpha="0"
|
|
10
|
+
android:fillAlpha="0"/>
|
|
11
|
+
<path
|
|
12
|
+
android:pathData="M9.867,50.977C10.969,50.977 11.859,50.602 12.984,49.945L48.773,29.133C51,27.867 51.82,26.977 51.82,25.5C51.82,24.047 51,23.156 48.773,21.867L12.984,1.078C11.859,0.422 10.969,0.023 9.867,0.023C7.852,0.023 6.586,1.547 6.586,3.961L6.586,47.063C6.586,49.453 7.852,50.977 9.867,50.977Z"
|
|
13
|
+
android:fillColor="#ffffff"
|
|
14
|
+
android:fillAlpha="1"/>
|
|
15
|
+
</vector>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<!-- Shadow -->
|
|
3
|
+
<item>
|
|
4
|
+
<shape android:shape="rectangle">
|
|
5
|
+
<corners android:radius="5dp"/>
|
|
6
|
+
<solid android:color="#80000000"/> <!-- semi-transparent black for shadow -->
|
|
7
|
+
</shape>
|
|
8
|
+
</item>
|
|
9
|
+
<!-- Rounded corners -->
|
|
10
|
+
<item android:right="2dp" android:left="2dp" android:top="2dp" android:bottom="2dp">
|
|
11
|
+
<shape android:shape="rectangle">
|
|
12
|
+
<corners android:radius="5dp"/>
|
|
13
|
+
<solid android:color="@android:color/white"/>
|
|
14
|
+
</shape>
|
|
15
|
+
</item>
|
|
16
|
+
</layer-list>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:insetLeft="-4dp" android:insetRight="-4dp" >
|
|
3
|
+
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
4
|
+
<solid android:color="@android:color/transparent" />
|
|
5
|
+
<stroke
|
|
6
|
+
android:width="4dp"
|
|
7
|
+
android:color="@color/trim_color" />
|
|
8
|
+
</shape>
|
|
9
|
+
</inset>
|
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<RelativeLayout
|
|
3
|
-
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
-
xmlns:tools="http://schemas.android.com/tools"
|
|
2
|
+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
5
3
|
android:layout_width="match_parent"
|
|
6
4
|
android:layout_height="match_parent"
|
|
7
|
-
android:orientation="vertical"
|
|
8
|
-
>
|
|
5
|
+
android:orientation="vertical">
|
|
9
6
|
|
|
10
7
|
<RelativeLayout
|
|
11
|
-
android:id="@+id/layout_surface_view"
|
|
12
8
|
android:layout_width="match_parent"
|
|
13
9
|
android:layout_height="match_parent"
|
|
14
10
|
android:layout_above="@+id/layout"
|
|
15
11
|
android:background="@android:color/black"
|
|
16
|
-
android:gravity="center"
|
|
17
|
-
>
|
|
12
|
+
android:gravity="center">
|
|
18
13
|
|
|
19
|
-
<
|
|
14
|
+
<VideoView
|
|
20
15
|
android:id="@+id/video_loader"
|
|
21
16
|
android:layout_width="match_parent"
|
|
22
17
|
android:layout_height="match_parent"
|
|
23
|
-
|
|
18
|
+
/>
|
|
19
|
+
|
|
20
|
+
<FrameLayout
|
|
21
|
+
android:id="@+id/audioBannerView"
|
|
22
|
+
android:layout_width="match_parent"
|
|
23
|
+
android:layout_height="match_parent"
|
|
24
|
+
android:layout_marginStart="50dp"
|
|
25
|
+
android:layout_marginTop="50dp"
|
|
26
|
+
android:layout_marginEnd="50dp"
|
|
27
|
+
android:layout_marginBottom="50dp"
|
|
28
|
+
android:padding="50dp"
|
|
29
|
+
android:visibility="gone">
|
|
30
|
+
|
|
31
|
+
<ImageView
|
|
32
|
+
android:layout_width="match_parent"
|
|
33
|
+
android:layout_height="match_parent"
|
|
34
|
+
android:layout_gravity="center"
|
|
35
|
+
android:contentDescription="Airpods Max"
|
|
36
|
+
android:src="@drawable/airpodsmax"
|
|
37
|
+
/>
|
|
38
|
+
</FrameLayout>
|
|
24
39
|
|
|
25
40
|
</RelativeLayout>
|
|
26
41
|
|
|
@@ -29,87 +44,166 @@
|
|
|
29
44
|
android:layout_width="match_parent"
|
|
30
45
|
android:layout_height="wrap_content"
|
|
31
46
|
android:layout_alignParentBottom="true"
|
|
32
|
-
android:background="@android:color/black"
|
|
33
|
-
>
|
|
34
|
-
|
|
35
|
-
<!-- <TextView-->
|
|
36
|
-
<!-- android:id="@+id/video_shoot_tip"-->
|
|
37
|
-
<!-- android:layout_width="match_parent"-->
|
|
38
|
-
<!-- android:layout_height="30dp"-->
|
|
39
|
-
<!-- android:layout_alignParentLeft="true"-->
|
|
40
|
-
<!-- android:layout_alignParentStart="true"-->
|
|
41
|
-
<!-- android:layout_alignParentTop="true"-->
|
|
42
|
-
<!-- android:gravity="center"-->
|
|
43
|
-
<!-- android:textColor="@android:color/white"-->
|
|
44
|
-
<!-- android:textSize="12dp"-->
|
|
45
|
-
<!-- tools:text="拖动选择你要发表的10秒以内片段"-->
|
|
46
|
-
<!-- />-->
|
|
47
|
-
<FrameLayout
|
|
48
|
-
android:id="@+id/video_frames_layout"
|
|
49
|
-
android:layout_width="match_parent"
|
|
50
|
-
android:layout_height="60dp"
|
|
51
|
-
>
|
|
47
|
+
android:background="@android:color/black">
|
|
52
48
|
|
|
53
|
-
<androidx.recyclerview.widget.RecyclerView
|
|
54
|
-
android:id="@+id/video_frames_recyclerView"
|
|
55
|
-
android:layout_width="match_parent"
|
|
56
|
-
android:layout_height="50dp"
|
|
57
|
-
android:layout_gravity="bottom"
|
|
58
|
-
tools:background="@android:color/holo_green_light"
|
|
59
|
-
/>
|
|
60
49
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
android:layout_marginLeft="35dp"
|
|
67
|
-
android:contentDescription="@null"
|
|
68
|
-
android:src="@drawable/icon_seek_bar"
|
|
69
|
-
/>
|
|
50
|
+
<RelativeLayout
|
|
51
|
+
android:id="@+id/trimmerView"
|
|
52
|
+
android:layout_width="match_parent"
|
|
53
|
+
android:layout_height="50dp"
|
|
54
|
+
android:layout_margin="8dp">
|
|
70
55
|
|
|
71
56
|
<LinearLayout
|
|
57
|
+
android:id="@+id/thumbnailContainer"
|
|
72
58
|
android:layout_width="match_parent"
|
|
73
|
-
android:layout_height="
|
|
74
|
-
android:
|
|
59
|
+
android:layout_height="match_parent"
|
|
60
|
+
android:layout_marginHorizontal="20dp"
|
|
75
61
|
android:orientation="horizontal"
|
|
76
|
-
|
|
62
|
+
android:padding="4dp"
|
|
63
|
+
/>
|
|
77
64
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
android:background="@color/shadow_color"
|
|
83
|
-
/>
|
|
84
|
-
|
|
85
|
-
<LinearLayout
|
|
86
|
-
android:id="@+id/seekBarLayout"
|
|
87
|
-
android:layout_width="0dp"
|
|
88
|
-
android:layout_height="60dp"
|
|
89
|
-
android:layout_gravity="bottom"
|
|
90
|
-
android:layout_weight="1"
|
|
91
|
-
android:gravity="bottom"
|
|
92
|
-
android:orientation="vertical"
|
|
93
|
-
/>
|
|
65
|
+
<RelativeLayout
|
|
66
|
+
android:id="@+id/trimmerContainerWrapper"
|
|
67
|
+
android:layout_width="match_parent"
|
|
68
|
+
android:layout_height="match_parent">
|
|
94
69
|
|
|
95
70
|
<View
|
|
96
|
-
android:
|
|
71
|
+
android:id="@+id/trimmerContainerBg"
|
|
72
|
+
android:layout_width="match_parent"
|
|
97
73
|
android:layout_height="match_parent"
|
|
98
|
-
android:
|
|
99
|
-
android:
|
|
100
|
-
|
|
101
|
-
|
|
74
|
+
android:layout_toStartOf="@id/trailingHandle"
|
|
75
|
+
android:layout_toEndOf="@id/leadingHandle" />
|
|
76
|
+
|
|
77
|
+
<RelativeLayout
|
|
78
|
+
android:layout_width="match_parent"
|
|
79
|
+
android:layout_height="match_parent">
|
|
80
|
+
|
|
81
|
+
<View
|
|
82
|
+
android:id="@+id/leadingOverlay"
|
|
83
|
+
android:layout_width="20dp"
|
|
84
|
+
android:layout_height="match_parent"
|
|
85
|
+
android:layout_alignParentStart="true"
|
|
86
|
+
android:background="@color/shadow_color" />
|
|
87
|
+
|
|
88
|
+
<View
|
|
89
|
+
android:id="@+id/trimmerContainer"
|
|
90
|
+
android:layout_width="match_parent"
|
|
91
|
+
android:layout_height="match_parent"
|
|
92
|
+
android:layout_toStartOf="@id/trailingOverlay"
|
|
93
|
+
android:layout_toEndOf="@id/leadingOverlay"
|
|
94
|
+
android:background="@drawable/yellow_border" />
|
|
95
|
+
|
|
96
|
+
<View
|
|
97
|
+
android:id="@+id/progressIndicator"
|
|
98
|
+
android:layout_width="10dp"
|
|
99
|
+
android:layout_height="match_parent"
|
|
100
|
+
android:layout_marginHorizontal="20dp"
|
|
101
|
+
android:background="@drawable/rounded_progress_indicator" />
|
|
102
|
+
|
|
103
|
+
<View
|
|
104
|
+
android:id="@+id/trailingOverlay"
|
|
105
|
+
android:layout_width="20dp"
|
|
106
|
+
android:layout_height="match_parent"
|
|
107
|
+
android:layout_alignParentEnd="true"
|
|
108
|
+
android:background="@color/shadow_color" />
|
|
109
|
+
</RelativeLayout>
|
|
110
|
+
|
|
111
|
+
<FrameLayout
|
|
112
|
+
android:id="@+id/leadingHandle"
|
|
113
|
+
android:layout_width="20dp"
|
|
114
|
+
android:layout_height="match_parent"
|
|
115
|
+
android:layout_alignParentStart="true"
|
|
116
|
+
android:layout_centerVertical="true"
|
|
117
|
+
android:background="@drawable/rounded_yellow_left_background"
|
|
118
|
+
android:paddingVertical="10dp">
|
|
119
|
+
|
|
120
|
+
<ImageView
|
|
121
|
+
android:layout_width="20dp"
|
|
122
|
+
android:layout_height="match_parent"
|
|
123
|
+
android:contentDescription="LeadingHandle"
|
|
124
|
+
android:src="@drawable/chevron_compact_left"
|
|
125
|
+
android:tint="@color/black" />
|
|
126
|
+
</FrameLayout>
|
|
127
|
+
|
|
128
|
+
<FrameLayout
|
|
129
|
+
android:id="@+id/trailingHandle"
|
|
130
|
+
android:layout_width="20dp"
|
|
131
|
+
android:layout_height="match_parent"
|
|
132
|
+
android:layout_alignParentEnd="true"
|
|
133
|
+
android:layout_centerVertical="true"
|
|
134
|
+
android:background="@drawable/rounded_yellow_right_background"
|
|
135
|
+
android:paddingVertical="10dp">
|
|
136
|
+
|
|
137
|
+
<ImageView
|
|
138
|
+
android:layout_width="20dp"
|
|
139
|
+
android:layout_height="match_parent"
|
|
140
|
+
android:contentDescription="TrailingHandle"
|
|
141
|
+
android:src="@drawable/chevron_compact_right"
|
|
142
|
+
android:tint="@color/black" />
|
|
143
|
+
</FrameLayout>
|
|
144
|
+
|
|
145
|
+
</RelativeLayout>
|
|
146
|
+
|
|
147
|
+
</RelativeLayout>
|
|
148
|
+
|
|
149
|
+
<FrameLayout
|
|
150
|
+
android:id="@+id/timingStackView"
|
|
151
|
+
android:layout_width="match_parent"
|
|
152
|
+
android:layout_height="50dp"
|
|
153
|
+
android:layout_below="@+id/trimmerView"
|
|
154
|
+
android:layout_marginHorizontal="16dp"
|
|
155
|
+
android:orientation="horizontal"
|
|
156
|
+
android:visibility="visible">
|
|
157
|
+
|
|
158
|
+
<TextView
|
|
159
|
+
android:id="@+id/startTime"
|
|
160
|
+
android:layout_width="wrap_content"
|
|
161
|
+
android:layout_height="match_parent"
|
|
162
|
+
android:layout_gravity="left"
|
|
163
|
+
android:clickable="true"
|
|
164
|
+
android:focusable="true"
|
|
165
|
+
android:gravity="center"
|
|
166
|
+
android:padding="10dp"
|
|
167
|
+
android:text="00:00.00"
|
|
168
|
+
android:textColor="@android:color/white"
|
|
169
|
+
android:textSize="16sp" />
|
|
170
|
+
|
|
171
|
+
<TextView
|
|
172
|
+
android:id="@+id/currentTime"
|
|
173
|
+
android:layout_width="wrap_content"
|
|
174
|
+
android:layout_height="match_parent"
|
|
175
|
+
android:layout_gravity="center"
|
|
176
|
+
android:clickable="true"
|
|
177
|
+
android:focusable="true"
|
|
178
|
+
android:gravity="center"
|
|
179
|
+
android:padding="10dp"
|
|
180
|
+
android:text="00:00.00"
|
|
181
|
+
android:textColor="@android:color/white"
|
|
182
|
+
android:textSize="16sp" />
|
|
183
|
+
|
|
184
|
+
<TextView
|
|
185
|
+
android:id="@+id/endTime"
|
|
186
|
+
android:layout_width="wrap_content"
|
|
187
|
+
android:layout_height="match_parent"
|
|
188
|
+
android:layout_gravity="right"
|
|
189
|
+
android:clickable="true"
|
|
190
|
+
android:focusable="true"
|
|
191
|
+
android:gravity="center"
|
|
192
|
+
android:padding="10dp"
|
|
193
|
+
android:text="00:00.00"
|
|
194
|
+
android:textColor="@android:color/white"
|
|
195
|
+
android:textSize="16sp" />
|
|
196
|
+
|
|
102
197
|
</FrameLayout>
|
|
103
198
|
|
|
104
199
|
<FrameLayout
|
|
105
200
|
android:layout_width="match_parent"
|
|
106
201
|
android:layout_height="50dp"
|
|
107
|
-
android:layout_below="@+id/
|
|
202
|
+
android:layout_below="@+id/timingStackView"
|
|
108
203
|
android:layout_marginLeft="10dp"
|
|
109
204
|
android:layout_marginRight="10dp"
|
|
110
205
|
android:orientation="horizontal"
|
|
111
|
-
android:visibility="visible"
|
|
112
|
-
>
|
|
206
|
+
android:visibility="visible">
|
|
113
207
|
|
|
114
208
|
<TextView
|
|
115
209
|
android:id="@+id/cancelBtn"
|
|
@@ -128,7 +222,30 @@
|
|
|
128
222
|
android:layout_height="match_parent"
|
|
129
223
|
android:layout_gravity="center"
|
|
130
224
|
android:padding="12dp"
|
|
131
|
-
android:src="@drawable/
|
|
225
|
+
android:src="@drawable/play_fill"
|
|
226
|
+
android:tint="@color/white"
|
|
227
|
+
android:visibility="gone"
|
|
228
|
+
/>
|
|
229
|
+
|
|
230
|
+
<ImageView
|
|
231
|
+
android:id="@+id/failToLoadBtn"
|
|
232
|
+
android:layout_width="wrap_content"
|
|
233
|
+
android:layout_height="match_parent"
|
|
234
|
+
android:layout_gravity="center"
|
|
235
|
+
android:padding="12dp"
|
|
236
|
+
android:src="@drawable/exclamationmark_triangle_fill"
|
|
237
|
+
android:tint="@color/trim_color"
|
|
238
|
+
android:visibility="gone"
|
|
239
|
+
/>
|
|
240
|
+
|
|
241
|
+
<ProgressBar
|
|
242
|
+
android:id="@+id/loadingIndicator"
|
|
243
|
+
style="?android:attr/progressBarStyle"
|
|
244
|
+
android:layout_width="wrap_content"
|
|
245
|
+
android:layout_height="wrap_content"
|
|
246
|
+
android:layout_gravity="center"
|
|
247
|
+
android:padding="10dp"
|
|
248
|
+
android:indeterminateTint="@color/white"
|
|
132
249
|
/>
|
|
133
250
|
|
|
134
251
|
<TextView
|
|
@@ -140,7 +257,9 @@
|
|
|
140
257
|
android:padding="10dp"
|
|
141
258
|
android:text="@string/save"
|
|
142
259
|
android:textColor="#2196F3"
|
|
143
|
-
android:textSize="16dp"
|
|
260
|
+
android:textSize="16dp"
|
|
261
|
+
android:visibility="gone"
|
|
262
|
+
/>
|
|
144
263
|
|
|
145
264
|
</FrameLayout>
|
|
146
265
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
|
2
2
|
<resources>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<color name="colorPrimary">#3F51B5</color>
|
|
4
|
+
<color name="colorPrimaryDark">#303F9F</color>
|
|
5
|
+
<color name="colorAccent">#FF4081</color>
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
<color name="white">#ffffffff</color>
|
|
8
|
+
<color name="red">#aacc0000</color>
|
|
9
|
+
<color name="background_video_color">#2f3031</color>
|
|
10
|
+
<color name="background_progress_color">#6C6D6D</color>
|
|
11
|
+
<color name="progress_color">#aacc0000</color>
|
|
12
|
+
<color name="line_color">#FF15FF00</color>
|
|
13
|
+
<color name="shadow_color">#7F000000</color>
|
|
14
|
+
<color name="line_button">#565758</color>
|
|
15
|
+
<color name="black_translucent">#50000000</color>
|
|
16
|
+
<color name="top_bottom">#42BAF8</color>
|
|
17
|
+
<color name="trim_color">#f1d247</color>
|
|
18
|
+
<color name="black">#000000</color>
|
|
17
19
|
</resources>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AssetLoader.swift
|
|
3
|
+
// react-native-video-trim
|
|
4
|
+
//
|
|
5
|
+
// Created by ByteDance on 7/27/24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import AVFoundation
|
|
9
|
+
|
|
10
|
+
protocol AssetLoaderDelegate: AnyObject {
|
|
11
|
+
func assetLoader(_ loader: AssetLoader, didFailWithError error: Error, forKey key: String)
|
|
12
|
+
func assetLoaderDidSucceed(_ loader: AssetLoader)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class AssetLoader: NSObject {
|
|
16
|
+
var asset: AVURLAsset?
|
|
17
|
+
weak var delegate: AssetLoaderDelegate?
|
|
18
|
+
|
|
19
|
+
func loadAsset(url: URL, isVideoType: Bool) {
|
|
20
|
+
// Creating AVURLAsset (not blocking the main thread)
|
|
21
|
+
asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
|
|
22
|
+
let keys = ["duration", "tracks"]
|
|
23
|
+
|
|
24
|
+
// Asynchronous property loading
|
|
25
|
+
asset?.loadValuesAsynchronously(forKeys: keys) {
|
|
26
|
+
DispatchQueue.main.async {
|
|
27
|
+
self.assetLoaded(isVideoType: isVideoType)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private func assetLoaded(isVideoType: Bool) {
|
|
33
|
+
guard let asset = asset else { return }
|
|
34
|
+
|
|
35
|
+
let keys = ["duration", "tracks"]
|
|
36
|
+
for key in keys {
|
|
37
|
+
var error: NSError?
|
|
38
|
+
let status = asset.statusOfValue(forKey: key, error: &error)
|
|
39
|
+
|
|
40
|
+
if status == .failed {
|
|
41
|
+
if let error = error {
|
|
42
|
+
delegate?.assetLoader(self, didFailWithError: error, forKey: key)
|
|
43
|
+
}
|
|
44
|
+
return
|
|
45
|
+
} else if status == .cancelled {
|
|
46
|
+
delegate?.assetLoader(self, didFailWithError: NSError(domain: "AssetLoader", code: -1, userInfo: [NSLocalizedDescriptionKey: "\(key) loading was cancelled"]), forKey: key)
|
|
47
|
+
return
|
|
48
|
+
} else if status != .loaded {
|
|
49
|
+
delegate?.assetLoader(self, didFailWithError: NSError(domain: "AssetLoader", code: -1, userInfo: [NSLocalizedDescriptionKey: "\(key) is in an unknown state"]), forKey: key)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if isVideoType {
|
|
55
|
+
// Process the tracks to load the remaining properties
|
|
56
|
+
self.processAssetTracks()
|
|
57
|
+
} else {
|
|
58
|
+
delegate?.assetLoaderDidSucceed(self)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private func processAssetTracks() {
|
|
63
|
+
guard let asset = asset else { return }
|
|
64
|
+
|
|
65
|
+
let videoTracks = asset.tracks(withMediaType: .video)
|
|
66
|
+
guard let videoTrack = videoTracks.first else {
|
|
67
|
+
delegate?.assetLoader(self, didFailWithError: NSError(domain: "AssetLoader", code: -1, userInfo: [NSLocalizedDescriptionKey: "No video tracks found"]), forKey: "tracks")
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let trackKeys = ["naturalSize", "preferredTransform"]
|
|
72
|
+
videoTrack.loadValuesAsynchronously(forKeys: trackKeys) {
|
|
73
|
+
DispatchQueue.main.async {
|
|
74
|
+
self.trackPropertiesLoaded(track: videoTrack)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private func trackPropertiesLoaded(track: AVAssetTrack) {
|
|
80
|
+
var error: NSError?
|
|
81
|
+
|
|
82
|
+
let naturalSizeStatus = track.statusOfValue(forKey: "naturalSize", error: &error)
|
|
83
|
+
let preferredTransformStatus = track.statusOfValue(forKey: "preferredTransform", error: &error)
|
|
84
|
+
|
|
85
|
+
if naturalSizeStatus == .loaded, preferredTransformStatus == .loaded {
|
|
86
|
+
let naturalSize = track.naturalSize
|
|
87
|
+
let preferredTransform = track.preferredTransform
|
|
88
|
+
|
|
89
|
+
print("Natural size: \(naturalSize)")
|
|
90
|
+
print("Preferred transform: \(preferredTransform)")
|
|
91
|
+
delegate?.assetLoaderDidSucceed(self)
|
|
92
|
+
} else {
|
|
93
|
+
if let error = error {
|
|
94
|
+
let failedKey = naturalSizeStatus != .loaded ? "naturalSize" : "preferredTransform"
|
|
95
|
+
delegate?.assetLoader(self, didFailWithError: error, forKey: failedKey)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ErrorCode.swift
|
|
3
|
+
// react-native-video-trim
|
|
4
|
+
//
|
|
5
|
+
// Created by ByteDance on 7/27/24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
enum ErrorCode: String {
|
|
11
|
+
case trimmingFailed = "TRIMMING_FAILED"
|
|
12
|
+
case failToLoadVideo = "FAIL_TO_LOAD_VIDEO"
|
|
13
|
+
case failToSaveToPhoto = "FAIL_TO_SAVE_TO_PHOTO"
|
|
14
|
+
case failToShare = "FAIL_TO_SHARE"
|
|
15
|
+
case noPhotoPermission = "NO_PHOTO_PERMISSION"
|
|
16
|
+
}
|