-
Notifications
You must be signed in to change notification settings - Fork 6k
/
media3-migration.sh
390 lines (358 loc) · 16.8 KB
/
media3-migration.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#!/bin/bash
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
shopt -s extglob
PACKAGE_MAPPINGS='com.google.android.exoplayer2 androidx.media3.exoplayer
com.google.android.exoplayer2.analytics androidx.media3.exoplayer.analytics
com.google.android.exoplayer2.audio androidx.media3.exoplayer.audio
com.google.android.exoplayer2.castdemo androidx.media3.demo.cast
com.google.android.exoplayer2.container androidx.media3.container
com.google.android.exoplayer2.database androidx.media3.database
com.google.android.exoplayer2.decoder androidx.media3.decoder
com.google.android.exoplayer2.demo androidx.media3.demo.main
com.google.android.exoplayer2.drm androidx.media3.exoplayer.drm
com.google.android.exoplayer2.effect androidx.media3.effect
com.google.android.exoplayer2.ext.av1 androidx.media3.decoder.av1
com.google.android.exoplayer2.ext.cast androidx.media3.cast
com.google.android.exoplayer2.ext.cronet androidx.media3.datasource.cronet
com.google.android.exoplayer2.ext.ffmpeg androidx.media3.decoder.ffmpeg
com.google.android.exoplayer2.ext.flac androidx.media3.decoder.flac
com.google.android.exoplayer2.ext.ima androidx.media3.exoplayer.ima
com.google.android.exoplayer2.ext.leanback androidx.media3.ui.leanback
com.google.android.exoplayer2.ext.midi androidx.media3.decoder.midi
com.google.android.exoplayer2.ext.okhttp androidx.media3.datasource.okhttp
com.google.android.exoplayer2.ext.opus androidx.media3.decoder.opus
com.google.android.exoplayer2.ext.rtmp androidx.media3.datasource.rtmp
com.google.android.exoplayer2.ext.vp9 androidx.media3.decoder.vp9
com.google.android.exoplayer2.ext.workmanager androidx.media3.exoplayer.workmanager
com.google.android.exoplayer2.extractor androidx.media3.extractor
com.google.android.exoplayer2.gldemo androidx.media3.demo.gl
com.google.android.exoplayer2.mediacodec androidx.media3.exoplayer.mediacodec
com.google.android.exoplayer2.metadata androidx.media3.extractor.metadata
com.google.android.exoplayer2.muxer androidx.media3.muxer
com.google.android.exoplayer2.offline androidx.media3.exoplayer.offline
com.google.android.exoplayer2.playbacktests androidx.media3.test.exoplayer.playback
com.google.android.exoplayer2.robolectric androidx.media3.test.utils.robolectric
com.google.android.exoplayer2.scheduler androidx.media3.exoplayer.scheduler
com.google.android.exoplayer2.source androidx.media3.exoplayer.source
com.google.android.exoplayer2.source.dash androidx.media3.exoplayer.dash
com.google.android.exoplayer2.source.hls androidx.media3.exoplayer.hls
com.google.android.exoplayer2.source.rtsp androidx.media3.exoplayer.rtsp
com.google.android.exoplayer2.source.smoothstreaming androidx.media3.exoplayer.smoothstreaming
com.google.android.exoplayer2.surfacedemo androidx.media3.demo.surface
com.google.android.exoplayer2.testdata androidx.media3.test.data
com.google.android.exoplayer2.testutil androidx.media3.test.utils
com.google.android.exoplayer2.text androidx.media3.extractor.text
com.google.android.exoplayer2.trackselection androidx.media3.exoplayer.trackselection
com.google.android.exoplayer2.transformer androidx.media3.transformer
com.google.android.exoplayer2.transformerdemo androidx.media3.demo.transformer
com.google.android.exoplayer2.ui androidx.media3.ui
com.google.android.exoplayer2.upstream androidx.media3.datasource
com.google.android.exoplayer2.upstream.cache androidx.media3.datasource.cache
com.google.android.exoplayer2.upstream.crypto androidx.media3.exoplayer.upstream.crypto
com.google.android.exoplayer2.util androidx.media3.common.util
com.google.android.exoplayer2.util androidx.media3.exoplayer.util
com.google.android.exoplayer2.video androidx.media3.exoplayer.video'
CLASS_RENAMINGS='com.google.android.exoplayer2.ui.StyledPlayerView androidx.media3.ui.PlayerView
StyledPlayerView PlayerView
com.google.android.exoplayer2.ui.StyledPlayerControlView androidx.media3.ui.PlayerControlView
StyledPlayerControlView PlayerControlView
com.google.android.exoplayer2.ExoPlayerLibraryInfo androidx.media3.common.MediaLibraryInfo
ExoPlayerLibraryInfo MediaLibraryInfo
com.google.android.exoplayer2.SimpleExoPlayer androidx.media3.exoplayer.ExoPlayer
SimpleExoPlayer ExoPlayer'
CLASS_MAPPINGS='com.google.android.exoplayer2.text.span androidx.media3.common.text HorizontalTextInVerticalContextSpan LanguageFeatureSpan RubySpan SpanUtil TextAnnotation TextEmphasisSpan
com.google.android.exoplayer2.text androidx.media3.common.text CueGroup Cue
com.google.android.exoplayer2.text androidx.media3.exoplayer.text ExoplayerCuesDecoder SubtitleDecoderFactory TextOutput TextRenderer
com.google.android.exoplayer2.upstream.crypto androidx.media3.datasource AesCipherDataSource AesCipherDataSink AesFlushingCipher
com.google.android.exoplayer2.util androidx.media3.common.util AtomicFile Assertions BitmapLoader BundleableUtil BundleUtil Clock ClosedSource CodecSpecificDataUtil ColorParser ConditionVariable Consumer CopyOnWriteMultiset EGLSurfaceTexture GlProgram GlUtil HandlerWrapper LibraryLoader ListenerSet Log LongArray MediaFormatUtil NetworkTypeObserver NonNullApi NotificationUtil NullableType ParsableBitArray ParsableByteArray RepeatModeUtil RunnableFutureTask Size SystemClock SystemHandlerWrapper TimedValueQueue TimestampAdjuster TraceUtil UnknownNull UnstableApi UriUtil Util XmlPullParserUtil
com.google.android.exoplayer2.util androidx.media3.common DebugViewProvider Effect ErrorMessageProvider FlagSet FileTypes FrameInfo GlObjectsProvider GlTextureInfo VideoFrameProcessingException VideoFrameProcessor OnInputFrameProcessedListener MimeTypes PriorityTaskManager SurfaceInfo
com.google.android.exoplayer2.metadata androidx.media3.common Metadata
com.google.android.exoplayer2.metadata androidx.media3.exoplayer.metadata MetadataDecoderFactory MetadataOutput MetadataRenderer
com.google.android.exoplayer2.audio androidx.media3.common AudioAttributes AuxEffectInfo
com.google.android.exoplayer2.ui androidx.media3.common AdOverlayInfo AdViewProvider
com.google.android.exoplayer2.source.ads androidx.media3.common AdPlaybackState
com.google.android.exoplayer2.source androidx.media3.common MediaPeriodId TrackGroup
com.google.android.exoplayer2.offline androidx.media3.common StreamKey
com.google.android.exoplayer2.ui androidx.media3.exoplayer.offline DownloadNotificationHelper
com.google.android.exoplayer2.trackselection androidx.media3.common TrackSelectionParameters TrackSelectionOverride
com.google.android.exoplayer2.video androidx.media3.common ColorInfo VideoSize VideoGraph PreviewingVideoGraph
com.google.android.exoplayer2.upstream androidx.media3.common DataReader
com.google.android.exoplayer2.upstream androidx.media3.exoplayer.upstream Allocation Allocator BandwidthMeter CachedRegionTracker DefaultAllocator DefaultBandwidthMeter DefaultLoadErrorHandlingPolicy Loader LoaderErrorThrower ParsingLoadable SlidingPercentile TimeToFirstByteEstimator
com.google.android.exoplayer2.audio androidx.media3.extractor AacUtil Ac3Util Ac4Util DtsUtil MpegAudioUtil OpusUtil WavUtil
com.google.android.exoplayer2.util androidx.media3.container NalUnitUtil ParsableNalUnitBitArray
com.google.android.exoplayer2.metadata.mp4 androidx.media3.container MdtaMetadataEntry
com.google.android.exoplayer2.video androidx.media3.extractor AvcConfig DolbyVisionConfig HevcConfig
com.google.android.exoplayer2.decoder androidx.media3.exoplayer DecoderCounters DecoderReuseEvaluation
com.google.android.exoplayer2.util androidx.media3.exoplayer MediaClock StandaloneMediaClock
com.google.android.exoplayer2 androidx.media3.exoplayer FormatHolder PlayerMessage
com.google.android.exoplayer2 androidx.media3.common BasePlayer BundleListRetriever Bundleable ControlDispatcher C DefaultControlDispatcher DeviceInfo ErrorMessageProvider ExoPlayerLibraryInfo Format ForwardingPlayer HeartRating IllegalSeekPositionException LegacyMediaPlayerWrapper MediaItem MediaMetadata ParserException PercentageRating PlaybackException PlaybackParameters Player PositionInfo Rating SimpleBasePlayer StarRating ThumbRating Timeline Tracks
com.google.android.exoplayer2.drm androidx.media3.common DrmInitData'
DEPENDENCY_MAPPINGS='exoplayer media3-exoplayer
exoplayer-common media3-common
exoplayer-core media3-exoplayer
exoplayer-dash media3-exoplayer-dash
exoplayer-database media3-database
exoplayer-datasource media-datasource
exoplayer-decoder media3-decoder
exoplayer-extractor media3-extractor
exoplayer-hls media3-exoplayer-hls
exoplayer-robolectricutils media3-test-utils-robolectric
exoplayer-rtsp media3-exoplayer-rtsp
exoplayer-smoothstreaming media3-exoplayer-smoothstreaming
exoplayer-testutils media3-test-utils
exoplayer-transformer media3-transformer
exoplayer-effect media3-effect
exoplayer-ui media3-ui
extension-cast media3-cast
extension-cronet media3-datasource-cronet
extension-ima media3-exoplayer-ima
extension-leanback media3-ui-leanback
extension-okhttp media3-datasource-okhttp
extension-rtmp media3-datasource-rtmp
extension-workmanager media3-exoplayer-workmanager'
# Rewrites classes, packages and dependencies from the legacy ExoPlayer package structure
# to androidx.media3 structure.
MEDIA3_VERSION="1.1.1"
LEGACY_PEER_VERSION="2.19.1"
function usage() {
echo "usage: $0 [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]"
echo " PROJECT_ROOT: path to your project root (location of 'gradlew')"
echo " -p: list package mappings and then exit"
echo " -c: list class mappings (precedence over package mappings) and then exit"
echo " -d: list dependency mappings and then exit"
echo " -m: migrate packages, classes and dependencies to AndroidX Media3"
echo " -l: list files that will be considered for rewrite and then exit"
echo " -x: exclude the path from the list of file to be changed: 'app/src/test'"
echo " -f: force the action even when validation fails"
echo " -v: print the exoplayer2/media3 version strings of this script and exit"
echo " --noclean : Do not call './gradlew clean' in project directory."
echo " -h, --help: show this help text"
}
function print_pairs {
while read -r line;
do
IFS=' ' read -ra PAIR <<< "$line"
printf "%-55s %-30s\n" "${PAIR[0]}" "${PAIR[1]}"
done <<< "$(echo "$@")"
}
function print_class_mappings {
while read -r mapping;
do
old=$(echo "$mapping" | cut -d ' ' -f1)
new=$(echo "$mapping" | cut -d ' ' -f2)
classes=$(echo "$mapping" | cut -d ' ' -f3-)
for clazz in $classes;
do
printf "%-80s %-30s\n" "$old.$clazz" "$new.$clazz"
done
done <<< "$(echo "$CLASS_MAPPINGS" | sort)"
}
ERROR_COUNTER=0
VALIDATION_ERRORS=''
function add_validation_error {
let ERROR_COUNTER++
VALIDATION_ERRORS+="\033[31m[$ERROR_COUNTER] ->\033[0m ${1}"
}
function validate_exoplayer_version() {
has_exoplayer_dependency=''
while read -r file;
do
local version
version=$(grep -m 1 "com\.google\.android\.exoplayer:" "$file" | cut -d ":" -f3 | tr -d \" | tr -d \')
if [[ ! -z $version ]] && [[ ! "$version" =~ $LEGACY_PEER_VERSION ]];
then
add_validation_error "The version does not match '$LEGACY_PEER_VERSION'. \
Update to '$LEGACY_PEER_VERSION' or use the migration script matching your \
current version. Current version '$version' found in\n $file\n"
fi
done <<< "$(find . -type f -name "build.gradle")"
}
function validate_string_not_contained {
local pattern=$1 # regex
local failure_message=$2
while read -r file;
do
if grep -q -e "$pattern" "$file";
then
add_validation_error "$failure_message:\n $file\n"
fi
done <<< "$files"
}
function validate_string_patterns {
validate_string_not_contained \
'com\.google\.android\.exoplayer2\..*\*' \
'Replace wildcard import statements with fully qualified import statements';
validate_string_not_contained \
'com\.google\.android\.exoplayer2\.ui\.PlayerView' \
'Migrate PlayerView to StyledPlayerView before migrating';
validate_string_not_contained \
'LegacyPlayerView' \
'Migrate LegacyPlayerView to StyledPlayerView before migrating';
validate_string_not_contained \
'com\.google\.android\.exoplayer2\.ext\.mediasession' \
'The MediaSessionConnector is integrated in androidx.media3.session.MediaSession'
}
SED_CMD_INPLACE='sed --in-place=.bak '
if [[ "$OSTYPE" == "darwin"* ]]; then
SED_CMD_INPLACE="sed -i .bak "
fi
MIGRATE_FILES='1'
LIST_FILES_ONLY='1'
PRINT_CLASS_MAPPINGS='1'
PRINT_PACKAGE_MAPPINGS='1'
PRINT_DEPENDENCY_MAPPINGS='1'
PRINT_VERSION='1'
NO_CLEAN='1'
FORCE='1'
IGNORE_VERSION='1'
EXCLUDED_PATHS=''
while [[ $1 =~ ^-.* ]];
do
case "$1" in
-m ) MIGRATE_FILES='';;
-l ) LIST_FILES_ONLY='';;
-c ) PRINT_CLASS_MAPPINGS='';;
-p ) PRINT_PACKAGE_MAPPINGS='';;
-d ) PRINT_DEPENDENCY_MAPPINGS='';;
-v ) PRINT_VERSION='';;
-f ) FORCE='';;
-x ) shift; EXCLUDED_PATHS="$(printf "%s\n%s" $EXCLUDED_PATHS $1)";;
--noclean ) NO_CLEAN='';;
* ) usage && exit 1;;
esac
shift
done
if [[ -z $PRINT_DEPENDENCY_MAPPINGS ]];
then
print_pairs "$DEPENDENCY_MAPPINGS"
exit 0
elif [[ -z $PRINT_PACKAGE_MAPPINGS ]];
then
print_pairs "$PACKAGE_MAPPINGS"
exit 0
elif [[ -z $PRINT_CLASS_MAPPINGS ]];
then
print_class_mappings
exit 0
elif [[ -z $PRINT_VERSION ]];
then
echo "$LEGACY_PEER_VERSION -> $MEDIA3_VERSION. This script is written to migrate from ExoPlayer $LEGACY_PEER_VERSION to AndroidX Media3 $MEDIA3_VERSION"
exit 0
elif [[ -z $1 ]];
then
usage
exit 1
fi
if [[ ! -f $1/gradlew ]];
then
echo "directory seems not to exist or is not a gradle project (missing 'gradlew')"
usage
exit 1
fi
PROJECT_ROOT=$1
cd "$PROJECT_ROOT"
# Create the set of files to transform
exclusion="/build/|/.idea/|/res/drawable|/res/color|/res/mipmap|/res/values|"
if [[ ! -z $EXCLUDED_PATHS ]];
then
while read -r path;
do
exclusion="$exclusion./$path|"
done <<< "$EXCLUDED_PATHS"
fi
files=$(find . -name '*\.java' -o -name '*\.kt' -o -name '*\.xml' | grep -Ev "'$exclusion'")
# Validate project and exit in case of validation errors
validate_string_patterns
validate_exoplayer_version "$PROJECT_ROOT"
if [[ ! -z $FORCE && ! -z "$VALIDATION_ERRORS" ]];
then
echo "============================================="
echo "Validation errors (use -f to force execution)"
echo "---------------------------------------------"
echo -e "$VALIDATION_ERRORS"
exit 1
fi
if [[ -z $LIST_FILES_ONLY ]];
then
echo "$files" | cut -c 3-
find . -type f -name 'build\.gradle' | cut -c 3-
exit 0
fi
# start migration after successful validation or when forced to disregard validation
# errors
if [[ ! -z "$MIGRATE_FILES" ]];
then
echo "nothing to do"
usage
exit 0
fi
if [[ ! -z $NO_CLEAN ]];
then
./gradlew clean
fi
# create expressions for class renamings
renaming_expressions=''
while read -r renaming;
do
src=$(echo "$renaming" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$renaming" | cut -d ' ' -f2)
renaming_expressions+="-e s/$src/$dest/g "
done <<< "$CLASS_RENAMINGS"
# create expressions for class mappings
classes_expressions=''
while read -r mapping;
do
src=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$mapping" | cut -d ' ' -f2)
classes=$(echo "$mapping" | cut -d ' ' -f3-)
for clazz in $classes;
do
classes_expressions+="-e s/$src\.$clazz/$dest.$clazz/g "
done
done <<< "$CLASS_MAPPINGS"
# create expressions for package mappings
packages_expressions=''
while read -r mapping;
do
src=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
dest=$(echo "$mapping" | cut -d ' ' -f2)
packages_expressions+="-e s/$src/$dest/g "
done <<< "$PACKAGE_MAPPINGS"
# do search and replace with expressions in each selected file
while read -r file;
do
echo "migrating $file"
expr="$renaming_expressions $classes_expressions $packages_expressions"
$SED_CMD_INPLACE $expr $file
rm ${file}.bak
done <<< "$files"
# create expressions for dependencies in gradle files
EXOPLAYER_GROUP="com\.google\.android\.exoplayer"
MEDIA3_GROUP="androidx.media3"
dependency_expressions=""
while read -r mapping
do
OLD=$(echo "$mapping" | cut -d ' ' -f1 | sed -e 's/\./\\\./g')
NEW=$(echo "$mapping" | cut -d ' ' -f2)
dependency_expressions="$dependency_expressions -e s/$EXOPLAYER_GROUP:$OLD:.*\"/$MEDIA3_GROUP:$NEW:$MEDIA3_VERSION\"/g -e s/$EXOPLAYER_GROUP:$OLD:.*'/$MEDIA3_GROUP:$NEW:$MEDIA3_VERSION'/"
done <<< "$DEPENDENCY_MAPPINGS"
## do search and replace for dependencies in gradle files
while read -r build_file;
do
echo "migrating build file $build_file"
$SED_CMD_INPLACE $dependency_expressions $build_file
rm ${build_file}.bak
done <<< "$(find . -type f -name 'build\.gradle')"