├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── country.aac │ ├── country.mp3 │ ├── marriage.mp3 │ └── sky_music.mp3 │ ├── java │ └── com │ │ └── video │ │ └── edit │ │ ├── MyApplication.java │ │ ├── activity │ │ ├── CameraEffectActivity.kt │ │ ├── DecodeActivity.java │ │ ├── MainActivity.kt │ │ ├── MainActivity2.java │ │ ├── VideoAudioFilterActivity.java │ │ ├── VideoClipActivity.kt │ │ ├── VideoFilterActivity.kt │ │ ├── VideoProgressActivity.kt │ │ ├── VideoReverseEditActivity.java │ │ └── VideoWaterMaskActivity.java │ │ ├── ext │ │ ├── EffectConfigs.java │ │ ├── FileUtils.java │ │ ├── FilterConfigs.java │ │ ├── MusicConfigs.java │ │ ├── PreferenceUtils.java │ │ └── SdkConfig.java │ │ ├── filter │ │ ├── MyPreviewFilter.java │ │ ├── MyRenderer.kt │ │ └── ShaderUtil.kt │ │ └── view │ │ ├── BaseThumbnailAdapter.java │ │ ├── BottomDialogFragment.java │ │ ├── Camera2BasicFragment.kt │ │ ├── ClipContainer.kt │ │ └── ClipContainerView.java │ └── res │ ├── anim │ ├── anim_slid_in_bottom.xml │ └── anim_slid_out_bottom.xml │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable-xhdpi │ ├── filter_daqiang.png │ ├── ic_beauty_face.png │ ├── ic_beauty_no.png │ ├── ic_beauty_recommend.png │ ├── ic_beauty_red.png │ ├── ic_beauty_white.png │ ├── ic_bg_video_next.png │ ├── ic_effect.png │ ├── ic_filter_fennen.png │ ├── ic_filter_huaijiu.png │ ├── ic_filter_landiao.png │ ├── ic_filter_langman.png │ ├── ic_filter_qingliang.png │ ├── ic_filter_qinxin.png │ ├── ic_filter_rixi.png │ ├── ic_filter_weimei.png │ ├── ic_motion_effect_1.png │ ├── ic_motion_effect_10.png │ ├── ic_motion_effect_11.png │ ├── ic_motion_effect_2.png │ ├── ic_motion_effect_3.png │ ├── ic_motion_effect_4.png │ ├── ic_motion_effect_5.png │ ├── ic_motion_effect_6.png │ ├── ic_motion_effect_7.png │ ├── ic_motion_effect_8.png │ ├── ic_motion_effect_9.png │ ├── ic_record_beauty_close.png │ ├── ic_record_filter.png │ ├── ic_video_clip_framebar_left.png │ ├── ic_video_clip_framebar_right.png │ ├── ic_video_record_back.png │ ├── lan.png │ ├── music_icon.png │ └── triangle.png │ ├── drawable │ ├── app_frame_preview_mode_bg.xml │ ├── bg_beauty_change.xml │ ├── bg_item_beauty_select.xml │ ├── bg_record_beauty_panel.xml │ ├── ic_launcher_background.xml │ ├── layer_action_progress.xml │ ├── left_frame.xml │ ├── progress_bar_ct.xml │ ├── record_mask_bottom.xml │ ├── record_mask_top.xml │ ├── right_frame.xml │ └── round_bg.xml │ ├── layout │ ├── activity_audio_filter.xml │ ├── activity_main.xml │ ├── activity_video_clip.xml │ ├── activity_video_edit.xml │ ├── activity_video_reverse.xml │ ├── activity_video_watermask.xml │ ├── bottom_dialog_fragment_layout.xml │ ├── camera_effect_activity_layout.xml │ ├── fragment_camera2_basic.xml │ ├── item_layout.xml │ ├── item_record_beauty.xml │ └── video_process_activity_layout.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── raw │ ├── dyf.glsl │ ├── fragment.glsl │ └── vertex.glsl │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── audiolibrary ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── CMakeLists.txt │ ├── audio_jni.cpp │ └── soundtouch │ │ ├── AAFilter.cpp │ │ ├── AAFilter.h │ │ ├── BPMDetect.cpp │ │ ├── BPMDetect.h │ │ ├── FIFOSampleBuffer.cpp │ │ ├── FIFOSampleBuffer.h │ │ ├── FIFOSamplePipe.h │ │ ├── FIRFilter.cpp │ │ ├── FIRFilter.h │ │ ├── InterpolateCubic.cpp │ │ ├── InterpolateCubic.h │ │ ├── InterpolateLinear.cpp │ │ ├── InterpolateLinear.h │ │ ├── InterpolateShannon.cpp │ │ ├── InterpolateShannon.h │ │ ├── PeakFinder.cpp │ │ ├── PeakFinder.h │ │ ├── RateTransposer.cpp │ │ ├── RateTransposer.h │ │ ├── STTypes.h │ │ ├── SoundTouch.cpp │ │ ├── SoundTouch.h │ │ ├── TDStretch.cpp │ │ ├── TDStretch.h │ │ ├── WavFile.cpp │ │ ├── WavFile.h │ │ ├── cpu_detect.h │ │ ├── cpu_detect_x86.cpp │ │ ├── mmx_optimized.cpp │ │ └── sse_optimized.cpp │ └── java │ └── com │ └── jeffmony │ └── audioeffect │ └── AudioProcess.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── playerLibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── video │ │ └── player │ │ ├── MediaItem.java │ │ ├── MediaUtils.java │ │ ├── ThumbExoPlayerView.kt │ │ ├── ToastExt.kt │ │ ├── VideoClip.java │ │ ├── VideoFrameExtractor.java │ │ ├── VideoItem.kt │ │ ├── ext.kt │ │ ├── player │ │ ├── MyLoadControl.java │ │ ├── VideoPlayTimeController.kt │ │ ├── VideoPlayer.kt │ │ ├── VideoPlayerOfExoPlayer.kt │ │ ├── VideoPlayerOfMediaPlayer.kt │ │ ├── mp │ │ │ ├── TextureSurfaceRenderer.java │ │ │ └── TextureSurfaceRenderer2.java │ │ └── player.kt │ │ ├── util │ │ ├── GlUtil.java │ │ ├── RawResourceReader.java │ │ ├── ShaderHelper.java │ │ └── VideoUtil.java │ │ └── util_ext.kt │ └── res │ ├── layout │ └── baseres_toast_layout.xml │ ├── raw │ ├── def_vertext.glsl │ ├── fragment_canying.glsl │ ├── fragment_flash.glsl │ ├── fragment_itch.glsl │ ├── fragment_scale.glsl │ ├── fragment_shake.glsl │ ├── fragment_sharder.glsl │ ├── fragment_soulout.glsl │ ├── fragment_split4.glsl │ └── vetext_sharder.glsl │ └── values │ ├── colors.xml │ └── strings.xml ├── settings.gradle └── videoEditSdk ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── assets └── filters │ ├── filter_fennen.png │ ├── filter_huaijiu.png │ ├── filter_landiao.png │ ├── filter_langman.png │ ├── filter_qingliang.png │ ├── filter_qingxin.png │ ├── filter_rixi.png │ ├── filter_weimei.png │ ├── filter_white.png │ ├── lookup_vertigo.png │ ├── skin_gray.png │ └── skin_lookup.png ├── java └── com │ └── video │ └── process │ ├── AudioProcessorManager.java │ ├── VideoProcessorManager.java │ ├── compose │ ├── audio │ │ ├── AudioChannel.java │ │ ├── AudioComposer.java │ │ ├── IAudioComposer.java │ │ ├── Pcm2Wav.java │ │ └── RemixAudioComposer.java │ ├── filter │ │ ├── GlBilateralComposeFilter.java │ │ ├── GlBoxBlurComposeFilter.java │ │ ├── GlBulgeDistortionComposeFilter.java │ │ ├── GlCGAColorspaceComposeFilter.java │ │ ├── GlComposeFilter.java │ │ ├── GlGaussianBlurComposeFilter.java │ │ ├── GlGrayScaleComposeFilter.java │ │ ├── GlHazeComposeFilter.java │ │ ├── GlInvertComposeFilter.java │ │ ├── GlLut512ComposeFilter.java │ │ ├── GlLutComposeFilter.java │ │ ├── GlMonochromeComposeFilter.java │ │ ├── GlOverlayComposeFilter.java │ │ ├── GlSepiaComposeFilter.java │ │ ├── GlSharpenComposeFilter.java │ │ ├── GlSphereRefractionComposeFilter.java │ │ ├── GlToneCurveComposeFilter.java │ │ ├── GlVignetteComposeFilter.java │ │ ├── GlWatermarkComposeFilter.java │ │ └── IResolutionFilter.java │ └── video │ │ ├── FrameBufferObjectOutputSurface.java │ │ ├── MediaCodecBufferCompatWrapper.java │ │ ├── Mp4Composer.java │ │ ├── Mp4ComposerEngine.java │ │ ├── MuxRender.java │ │ └── VideoComposer.java │ ├── exception │ └── VideoProcessException.java │ ├── listener │ ├── IVideoProcessorListener.java │ └── IVideoReverseListener.java │ ├── model │ ├── CustomFillMode.java │ ├── FillMode.java │ ├── ProcessParams.java │ ├── Rotation.java │ ├── TrackType.java │ ├── VideoRange.java │ └── VideoSize.java │ ├── preview │ ├── EFrameBufferObjectRenderer.java │ ├── EFramebufferObject.java │ ├── EPlayerRenderer.java │ ├── EPlayerView.java │ ├── ESurfaceTexture.java │ ├── EglUtil.java │ ├── GlPlayerView.kt │ ├── PlayerScaleType.java │ ├── TextureSurfaceFBORenderer.java │ ├── VideoTextureSurfaceRenderer2.java │ ├── chooser │ │ └── EConfigChooser.java │ ├── contextfactory │ │ └── EContextFactory.java │ ├── custfilter │ │ ├── GLImageAmaroFilter.java │ │ ├── GLImageBeautyHighPassFilter.java │ │ ├── GLImageBlackWhiteFilter.java │ │ ├── GLImageComplexionBeautyFilter.java │ │ ├── GLImageGaussPassFilter.java │ │ ├── Gl4SplitFilter.java │ │ ├── GlBeautyBlurFilter.java │ │ ├── GlBeautyFilter.java │ │ ├── GlBeautyGroupFilter.java │ │ ├── GlFlashFliter.java │ │ ├── GlHuanJueFliter.java │ │ ├── GlItchFilter.java │ │ ├── GlPngFliter.java │ │ ├── GlScaleFilter.java │ │ ├── GlShakeFilter.java │ │ └── GlSoulOutFilter.java │ └── filter │ │ ├── FilterType.java │ │ ├── GlBilateralFilter.java │ │ ├── GlBoxBlurFilter.java │ │ ├── GlBulgeDistortionFilter.java │ │ ├── GlCGAColorspaceFilter.java │ │ ├── GlFilter.java │ │ ├── GlFilterConfig.java │ │ ├── GlFilterGroup.java │ │ ├── GlFilterList.java │ │ ├── GlFilterPeriod.java │ │ ├── GlGaussianBlurFilter.java │ │ ├── GlGrayScaleFilter.java │ │ ├── GlHazeFilter.java │ │ ├── GlInvertFilter.java │ │ ├── GlLookUpTableFilter.java │ │ ├── GlMonochromeFilter.java │ │ ├── GlOverlayFilter.java │ │ ├── GlPreviewFilter.java │ │ ├── GlSepiaFilter.java │ │ ├── GlSharpenFilter.java │ │ ├── GlSphereRefractionFilter.java │ │ ├── GlThreex3TextureSamplingFilter.java │ │ ├── GlToneCurveFilter.java │ │ ├── GlToneFilter.java │ │ ├── GlVignetteFilter.java │ │ └── GlWeakPixelInclusionFilter.java │ ├── surface │ ├── DecoderOutputSurface.java │ ├── DecoderSurface.java │ ├── DecoderSurface2.java │ ├── EncoderSurface.java │ ├── InputSurface.java │ ├── MPlayerView.java │ ├── MagicJni.java │ ├── OutputSurface.java │ ├── TextureRenderer.java │ └── VideoProcessConfig.java │ ├── thread │ ├── AudioProcessorThread.java │ ├── IVideoEncodeThread.java │ ├── VideoDecodeThread.java │ └── VideoEncodeThread.java │ └── utils │ ├── AudioUtils.java │ ├── GLESUtils.java │ ├── LogUtils.java │ ├── ScreenUtils.java │ ├── VideoCustomException.java │ ├── VideoUtils.java │ └── WorkThreadHandler.java ├── jni └── MagicJni.cpp └── res ├── drawable └── image1.jpg └── values └── strings.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | /.idea 13 | /soundtouchLib/.cxx 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MediaEditSdk 2 | 在原有https://github.com/JeffMony/VideoEditSDK的基础上完善 3 | 使用android原生的MediaExtractor,MediaCodec和OpenGL ES对视频进行编辑, 裁剪,滤镜, 特效等. 4 | 5 | #### 功能点 6 | 1. 视频播放 7 | 2. 视频裁剪 8 | 3. 视频帧预览 9 | 4. 裁剪区间动态可选择. 10 | 5. 美颜滤镜 11 | 6. OpenGL ES特效.特效叠加后视频生成 12 | 7. 摄像头预览时选择滤镜. --- 只支持L版本以上的手机 13 | 8. 分离音视频(待做) 14 | 9. 声音合成到视频上(待做) 15 | 16 | #### 使用 17 | 1. 必须是android 17 及以上版本 18 | 19 | ## 项目引用 20 | * [Mp4Composer-android](https://github.com/MasayukiSuda/Mp4Composer-android) 21 | * [android-transcoder](https://github.com/ypresto/android-transcoder) 22 | * [android-transcoder Japanese blog](http://qiita.com/yuya_presto/items/d48e29c89109b746d000) 23 | * [android-gpuimage](https://github.com/CyberAgent/android-gpuimage) 24 | * [Android MediaCodec stuff](http://bigflake.com/mediacodec/) 25 | * [grafika](https://github.com/google/grafika) 26 | * [libstagefright](https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/media/libstagefright) 27 | 28 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 30 9 | defaultConfig { 10 | applicationId "com.video.edit.demo" 11 | minSdkVersion 19 12 | targetSdkVersion 29 13 | versionCode 1 14 | versionName "1.0" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | shrinkResources false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | 29 | lintOptions { 30 | abortOnError false 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: 'libs', include: ['*.aar']) 36 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 37 | implementation 'androidx.appcompat:appcompat:1.0.0' 38 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 39 | 40 | implementation 'androidx.recyclerview:recyclerview:1.0.0' 41 | 42 | implementation project(':playerLibrary') 43 | implementation project(':videoEditSdk') 44 | } 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/assets/country.aac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/assets/country.aac -------------------------------------------------------------------------------- /app/src/main/assets/country.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/assets/country.mp3 -------------------------------------------------------------------------------- /app/src/main/assets/marriage.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/assets/marriage.mp3 -------------------------------------------------------------------------------- /app/src/main/assets/sky_music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/assets/sky_music.mp3 -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.video.edit; 2 | 3 | import android.app.Application; 4 | 5 | import com.video.edit.ext.SdkConfig; 6 | 7 | import java.io.File; 8 | 9 | public class MyApplication extends Application { 10 | 11 | @Override 12 | public void onCreate() { 13 | super.onCreate(); 14 | File sdkDir = SdkConfig.getVideoDir(this); 15 | if (!sdkDir.exists()) { 16 | sdkDir.mkdir(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/activity/CameraEffectActivity.kt: -------------------------------------------------------------------------------- 1 | package com.video.edit.activity 2 | 3 | import android.os.Build 4 | import android.os.Bundle 5 | import androidx.annotation.RequiresApi 6 | import androidx.appcompat.app.AppCompatActivity 7 | 8 | import com.video.edit.demo.R 9 | import com.video.edit.view.Camera2BasicFragment 10 | 11 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP) 12 | class CameraEffectActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.camera_effect_activity_layout) 17 | 18 | if (null == savedInstanceState) { 19 | supportFragmentManager.beginTransaction() 20 | .replace(R.id.container, Camera2BasicFragment.newInstance()) 21 | .commit() 22 | } 23 | } 24 | 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/activity/VideoReverseEditActivity.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.activity; 2 | 3 | import android.os.Bundle; 4 | import android.widget.Toast; 5 | 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | 9 | import com.google.android.exoplayer2.ui.PlayerView; 10 | import com.video.process.utils.LogUtils; 11 | import com.video.edit.demo.R; 12 | import com.video.player.player.VideoPlayer; 13 | import com.video.player.player.VideoPlayerOfExoPlayer; 14 | 15 | import java.io.File; 16 | 17 | public class VideoReverseEditActivity extends AppCompatActivity { 18 | 19 | private PlayerView mPlayerView; 20 | private String mMediaPath; 21 | private VideoPlayer mVideoPlayer; 22 | 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_video_reverse); 27 | mMediaPath = getIntent().getStringExtra("video_path"); 28 | LogUtils.i("MediaPath = " + mMediaPath); 29 | 30 | mPlayerView = findViewById(R.id.player_view); 31 | 32 | File mediaFile = new File(mMediaPath); 33 | if (!mediaFile.exists()) { 34 | Toast.makeText(this, "请更新videoPlayUrl变量为本地手机的视频文件地址", Toast.LENGTH_LONG).show(); 35 | } 36 | mVideoPlayer = new VideoPlayerOfExoPlayer(mPlayerView); 37 | mVideoPlayer.setupPlayer(this, mMediaPath); 38 | } 39 | 40 | @Override 41 | protected void onResume() { 42 | super.onResume(); 43 | } 44 | 45 | @Override 46 | protected void onPause() { 47 | super.onPause(); 48 | mVideoPlayer.pausePlayer(); 49 | } 50 | 51 | @Override 52 | protected void onStop() { 53 | super.onStop(); 54 | } 55 | 56 | @Override 57 | protected void onDestroy() { 58 | super.onDestroy(); 59 | mVideoPlayer.releasePlayer(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/activity/VideoWaterMaskActivity.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.activity; 2 | 3 | import android.os.Bundle; 4 | import android.widget.Toast; 5 | 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | 9 | import com.google.android.exoplayer2.ui.PlayerView; 10 | import com.video.process.utils.LogUtils; 11 | import com.video.edit.demo.R; 12 | import com.video.player.player.VideoPlayer; 13 | import com.video.player.player.VideoPlayerOfExoPlayer; 14 | 15 | import java.io.File; 16 | 17 | public class VideoWaterMaskActivity extends AppCompatActivity { 18 | 19 | private PlayerView mPlayerView; 20 | private String mMediaPath; 21 | private VideoPlayer mVideoPlayer; 22 | 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_video_watermask); 27 | mMediaPath = getIntent().getStringExtra("video_path"); 28 | LogUtils.i("MediaPath = " + mMediaPath); 29 | 30 | mPlayerView = findViewById(R.id.player_view); 31 | 32 | File mediaFile = new File(mMediaPath); 33 | if (!mediaFile.exists()) { 34 | Toast.makeText(this, "请更新videoPlayUrl变量为本地手机的视频文件地址", Toast.LENGTH_LONG).show(); 35 | } 36 | mVideoPlayer = new VideoPlayerOfExoPlayer(mPlayerView); 37 | mVideoPlayer.setupPlayer(this, mMediaPath); 38 | } 39 | 40 | @Override 41 | protected void onResume() { 42 | super.onResume(); 43 | } 44 | 45 | @Override 46 | protected void onPause() { 47 | super.onPause(); 48 | mVideoPlayer.pausePlayer(); 49 | } 50 | 51 | @Override 52 | protected void onStop() { 53 | super.onStop(); 54 | } 55 | 56 | @Override 57 | protected void onDestroy() { 58 | super.onDestroy(); 59 | mVideoPlayer.releasePlayer(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/EffectConfigs.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import android.content.Context; 4 | 5 | import com.video.edit.demo.R; 6 | import com.video.edit.view.BottomDialogFragment; 7 | import com.video.process.preview.custfilter.GLImageComplexionBeautyFilter; 8 | import com.video.process.preview.custfilter.Gl4SplitFilter; 9 | import com.video.process.preview.custfilter.GlFlashFliter; 10 | import com.video.process.preview.custfilter.GlHuanJueFliter; 11 | import com.video.process.preview.custfilter.GlItchFilter; 12 | import com.video.process.preview.custfilter.GlScaleFilter; 13 | import com.video.process.preview.custfilter.GlShakeFilter; 14 | import com.video.process.preview.custfilter.GlSoulOutFilter; 15 | import com.video.process.preview.filter.GlFilter; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | public class EffectConfigs { 21 | 22 | public static List createEffectOptions() { 23 | List result = new ArrayList<>(); 24 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "无特效", 0)); 25 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "灵魂出窍", 1)); 26 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "幻觉", 2)); 27 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "闪电", 3)); 28 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "毛刺", 4)); 29 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "缩放", 5)); 30 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "抖动", 6)); 31 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "四分镜", 7)); 32 | return result; 33 | } 34 | 35 | public static GlFilter getEffectFilterByName(String name, Context context) { 36 | if (name.equals("无特效")) { 37 | return new GlFilter(); 38 | } else if (name.equals("缩放")) { 39 | return new GlScaleFilter(context); 40 | } else if (name.equals("抖动")) { 41 | return new GlShakeFilter(context); 42 | } else if (name.equals("四分镜")) { 43 | return new Gl4SplitFilter(context); 44 | } else if (name.equals("灵魂出窍")) { 45 | return new GlSoulOutFilter(context); 46 | } else if (name.equals("幻觉")) { 47 | return new GlHuanJueFliter(context); 48 | } else if (name.equals("闪电")) { 49 | return new GlFlashFliter(context); 50 | } else if (name.equals("毛刺")) { 51 | return new GlItchFilter(context); 52 | } else { 53 | return new GLImageComplexionBeautyFilter(context); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | import java.io.FileInputStream; 7 | import java.io.InputStream; 8 | 9 | public class FileUtils { 10 | public static Bitmap decodeFile(String file) { 11 | FileInputStream fis = null; 12 | try { 13 | fis = new FileInputStream(file); 14 | return decodeInputStream(fis); 15 | } catch (Exception e) { 16 | 17 | } finally { 18 | if (fis != null) { 19 | try { 20 | fis.close(); 21 | } catch (Exception e) { 22 | 23 | } 24 | } 25 | } 26 | return null; 27 | } 28 | 29 | public static Bitmap decodeInputStream(InputStream is) { 30 | BitmapFactory.Options opt_decord = new BitmapFactory.Options(); 31 | opt_decord.inPurgeable = true; 32 | opt_decord.inInputShareable = true; 33 | Bitmap bitmap_ret = null; 34 | try { 35 | bitmap_ret = BitmapFactory.decodeStream(is, null, opt_decord); 36 | } catch (Exception e) { 37 | bitmap_ret = null; 38 | } 39 | return bitmap_ret; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/FilterConfigs.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import android.content.Context; 4 | 5 | import com.video.edit.demo.R; 6 | import com.video.edit.view.BottomDialogFragment; 7 | import com.video.process.preview.custfilter.GLImageComplexionBeautyFilter; 8 | import com.video.process.preview.custfilter.GlPngFliter; 9 | import com.video.process.preview.filter.GlFilter; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class FilterConfigs { 15 | 16 | public static List createFilterOptions() { 17 | List result = new ArrayList<>(); 18 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "无", 0)); 19 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "美颜", 1)); 20 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "美白", 2)); 21 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "浪漫", 3)); 22 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "清新", 4)); 23 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "唯美", 5)); 24 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "粉嫩", 6)); 25 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "怀旧", 7)); 26 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "蓝调", 8)); 27 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "清凉", 9)); 28 | result.add(new BottomDialogFragment.Option(R.drawable.filter_daqiang, "日系", 10)); 29 | return result; 30 | } 31 | 32 | public static GlFilter getFilterByName(String name, Context context) { 33 | if (name.equals("无")) { 34 | return new GlFilter(); 35 | } else if (name.equals("美颜")) { 36 | return new GLImageComplexionBeautyFilter(context); 37 | } else { 38 | return new GlPngFliter(context, getFilterPngByType(name)); 39 | } 40 | } 41 | 42 | public static String getFilterPngByType(String type) { 43 | if (type.equals("美白")) { 44 | return "filter_white"; 45 | } else if (type.equals("浪漫")) { 46 | return "filter_langman"; 47 | } else if (type.equals("清新")) { 48 | return "filter_qingxin"; 49 | } else if (type.equals("唯美")) { 50 | return "filter_weimei"; 51 | } else if (type.equals("粉嫩")) { 52 | return "filter_fennen"; 53 | } else if (type.equals("怀旧")) { 54 | return "filter_huaijiu"; 55 | } else if (type.equals("蓝调")) { 56 | return "filter_landiao"; 57 | } else if (type.equals("清凉")) { 58 | return "filter_qingliang"; 59 | } else if (type.equals("日系")) { 60 | return "filter_rixi"; 61 | } else { 62 | return "filter_white"; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/MusicConfigs.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import com.video.edit.demo.R; 4 | import com.video.edit.view.BottomDialogFragment; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | public class MusicConfigs { 10 | 11 | public static List createMusicOptions() { 12 | return Arrays.asList(new BottomDialogFragment.Option[] { 13 | new BottomDialogFragment.Option(R.drawable.filter_daqiang, "不选", 0), 14 | new BottomDialogFragment.Option(R.drawable.filter_daqiang, "静音", 1), 15 | new BottomDialogFragment.Option(R.drawable.filter_daqiang, "故乡", 2), 16 | new BottomDialogFragment.Option(R.drawable.filter_daqiang, "婚礼", 3), 17 | new BottomDialogFragment.Option(R.drawable.filter_daqiang, "天空", 4)}); 18 | } 19 | 20 | public static String getMusicByType(String option) { 21 | switch (option) { 22 | case "故乡": 23 | return "country.aac"; 24 | case "天空": 25 | return "sky_music.mp3"; 26 | case "婚礼": 27 | return "marriage.mp3"; 28 | default: 29 | return "None"; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/PreferenceUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | public class PreferenceUtils { 7 | private static final String NAME = "litedo"; 8 | 9 | public static final String FILTER_SELECTION_KEY = "filter_selection"; 10 | public static final String MUSIC_SELECTION_KEY = "music_selection"; 11 | 12 | public static void putInt(Context context, String key, int value) { 13 | if (context == null) return; 14 | SharedPreferences preferences = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); 15 | SharedPreferences.Editor editor = preferences.edit(); 16 | editor.putInt(key, value); 17 | editor.commit(); 18 | } 19 | 20 | public static int getInt(Context context, String key, int defVal) { 21 | if (context == null) return defVal; 22 | SharedPreferences preferences = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); 23 | return preferences.getInt(key, defVal); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/ext/SdkConfig.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.ext; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.File; 6 | 7 | public class SdkConfig { 8 | public static final int SPEED_RANGE = 30; 9 | public static final String DEFAULT_TEMP_VIDEO_LOCATION = "/storage/emulated/0/movies/process.mp4"; 10 | 11 | public static int MSG_UPDATE = 1; 12 | public static boolean USE_EXOPLAYER = true; 13 | 14 | // 对于长视频, 每隔3s截取一个缩略图 15 | public static int MAX_FRAME_INTERVAL_MS = 3 * 1000; 16 | 17 | // 默认显示10个缩略图 18 | public static int DEFAULT_FRAME_COUNT = 10; 19 | 20 | // 裁剪最小时间为3s 21 | public static int minSelection = 3000; // 最短3s 22 | 23 | // 裁剪最长时间为30s 24 | public static long maxSelection = 30000; // 最长30s 25 | 26 | public static File getVideoDir(Context context) { 27 | return new File(context.getExternalFilesDir("Video"), "EditDir"); 28 | } 29 | 30 | public static final String FILTER_DIALOG = "filter_dialog"; 31 | public static final String MUSIC_DIALOG = "music_dialog"; 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/video/edit/view/BaseThumbnailAdapter.java: -------------------------------------------------------------------------------- 1 | package com.video.edit.view; 2 | 3 | import android.text.TextUtils; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.video.edit.demo.R; 14 | import com.video.edit.ext.FileUtils; 15 | 16 | import java.util.List; 17 | 18 | public class BaseThumbnailAdapter extends RecyclerView.Adapter { 19 | 20 | private List mList; 21 | private int mWidth; 22 | 23 | public BaseThumbnailAdapter(List list, int itemWidth) { 24 | mList = list; 25 | mWidth = itemWidth; 26 | } 27 | 28 | @NonNull 29 | @Override 30 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 31 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); 32 | return new ViewHolder(view); 33 | } 34 | 35 | @Override 36 | public int getItemCount() { 37 | return mList.size(); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 42 | ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); 43 | layoutParams.width = mWidth; 44 | holder.itemView.setLayoutParams(layoutParams); 45 | if (!TextUtils.isEmpty(mList.get(position))) { 46 | holder.imageView.setImageBitmap(FileUtils.decodeFile(mList.get(position))); 47 | } else { 48 | holder.imageView.setImageResource(R.drawable.ic_launcher_background); 49 | } 50 | } 51 | } 52 | 53 | class ViewHolder extends RecyclerView.ViewHolder { 54 | TextView titleView; 55 | ImageView imageView; 56 | 57 | public ViewHolder(View itemView) { 58 | super(itemView); 59 | titleView = itemView.findViewById(R.id.title); 60 | imageView = itemView.findViewById(R.id.image); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_slid_in_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_slid_out_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/filter_daqiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/filter_daqiang.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_beauty_face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_beauty_face.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_beauty_no.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_beauty_no.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_beauty_recommend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_beauty_recommend.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_beauty_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_beauty_red.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_beauty_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_beauty_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_bg_video_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_bg_video_next.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_effect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_effect.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_fennen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_fennen.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_huaijiu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_huaijiu.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_landiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_landiao.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_langman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_langman.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_qingliang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_qingliang.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_qinxin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_qinxin.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_rixi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_rixi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_filter_weimei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_filter_weimei.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_10.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_11.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_7.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_8.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_motion_effect_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_motion_effect_9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_record_beauty_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_record_beauty_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_record_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_record_filter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_video_clip_framebar_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_video_clip_framebar_left.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_video_clip_framebar_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_video_clip_framebar_right.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_video_record_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/ic_video_record_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/lan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/lan.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/music_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/music_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/drawable-xhdpi/triangle.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/app_frame_preview_mode_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_beauty_change.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_item_beauty_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_record_beauty_panel.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layer_action_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/left_frame.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progress_bar_ct.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/record_mask_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/record_mask_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/right_frame.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_audio_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 15 | 16 | 28 | 29 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | 31 | 32 | 44 | 45 | 57 | 58 | 70 | 71 | 83 | 84 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_video_reverse.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_video_watermask.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/bottom_dialog_fragment_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 18 | 19 | 23 | 24 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 58 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /app/src/main/res/layout/camera_effect_activity_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_record_beauty.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 21 | 22 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/video_process_activity_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 18 | 19 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/raw/dyf.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision highp float; 3 | varying vec2 aCoordinate; 4 | uniform samplerExternalOES vTexture; 5 | uniform float saturation; 6 | void main() { 7 | vec2 uv = aCoordinate.xy; 8 | vec2 scaleCoordinate = vec2((saturation - 1.0) * 0.5 + uv.x / saturation , (saturation - 1.0) * 0.5 + uv.y / saturation); 9 | vec4 smoothColor = texture2D(vTexture, scaleCoordinate); // 计算红色通道偏移值 10 | vec4 shiftRedColor = texture2D(vTexture, scaleCoordinate + vec2(-0.1 * (saturation - 1.0), - 0.1 *(saturation - 1.0))); // 计算绿色通道偏移值 11 | vec4 shiftGreenColor = texture2D(vTexture, scaleCoordinate + vec2(-0.075 * (saturation - 1.0), - 0.075 *(saturation - 1.0))); // 计算蓝色偏移值 12 | vec4 shiftBlueColor = texture2D(vTexture, scaleCoordinate + vec2(-0.05 * (saturation - 1.0), - 0.05 *(saturation - 1.0))); 13 | vec3 resultColor = vec3(shiftRedColor.r, shiftGreenColor.g, shiftBlueColor.b); 14 | gl_FragColor = vec4(resultColor, smoothColor.a); 15 | } -------------------------------------------------------------------------------- /app/src/main/res/raw/fragment.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision mediump float; 3 | varying vec2 aCoordinate; 4 | uniform samplerExternalOES vTexture; 5 | 6 | uniform lowp float saturation; 7 | // Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham 8 | const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); 9 | 10 | 11 | 12 | void main(){ 13 | // gl_FragColor=texture2D(vTexture,aCoordinate); 14 | 15 | // lowp vec4 textureColor = texture2D(vTexture, aCoordinate); 16 | // lowp float luminance = dot(textureColor.rgb, luminanceWeighting); 17 | // lowp vec3 greyScaleColor = vec3(luminance); 18 | // gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); 19 | 20 | gl_FragColor = texture2D(vTexture, aCoordinate); 21 | } -------------------------------------------------------------------------------- /app/src/main/res/raw/vertex.glsl: -------------------------------------------------------------------------------- 1 | //#version 300 es 2 | attribute vec2 vPosition; 3 | attribute vec2 vCoordinate; 4 | varying vec2 aCoordinate; 5 | uniform mat4 uTexRotateMatrix; 6 | void main(){ 7 | gl_Position = uTexRotateMatrix * vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 ); 8 | aCoordinate=vCoordinate; 9 | } -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | #67ffec 7 | #99000000 8 | #000000 9 | #67ffec 10 | #ff324c 11 | #00000000 12 | #ffffff 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48dp 4 | 3dp 5 | 36dp 6 | 14dp 7 | 20dp 8 | 40dp 9 | 40dp 10 | 2dp 11 | 12dp 12 | 12dp 13 | 3dp 14 | 48dp 15 | 32dp 16 | 2dp 17 | 200dp 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | JeffVideoEditor 3 | Picture 4 | Info 5 | This sample needs camera permission. 6 | This device doesn\'t support Camera2 API. 7 | 8 | 16 | 17 | Record 18 | Stop 19 | This sample needs permission for camera and audio recording. 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /audiolibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.cxx 3 | .cxx 4 | -------------------------------------------------------------------------------- /audiolibrary/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | } 4 | 5 | android { 6 | compileSdkVersion 30 7 | 8 | defaultConfig { 9 | minSdkVersion 19 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | consumerProguardFiles "consumer-rules.pro" 15 | 16 | externalNativeBuild { 17 | cmake { 18 | cppFlags "-fexceptions" 19 | abiFilters "armeabi-v7a","arm64-v8a" 20 | } 21 | } 22 | } 23 | 24 | externalNativeBuild { 25 | cmake { 26 | path "src/main/cpp/CMakeLists.txt" 27 | version "3.10.2" 28 | } 29 | } 30 | 31 | buildTypes { 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | compileOptions { 38 | sourceCompatibility JavaVersion.VERSION_1_8 39 | targetCompatibility JavaVersion.VERSION_1_8 40 | } 41 | } 42 | 43 | dependencies { 44 | implementation 'androidx.appcompat:appcompat:1.1.0' 45 | } -------------------------------------------------------------------------------- /audiolibrary/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/audiolibrary/consumer-rules.pro -------------------------------------------------------------------------------- /audiolibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /audiolibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /audiolibrary/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | 8 | include_directories(./soundtouch) 9 | 10 | # Creates and names a library, sets it as either STATIC 11 | # or SHARED, and provides the relative paths to its source code. 12 | # You can define multiple libraries, and CMake builds them for you. 13 | # Gradle automatically packages shared libraries with your APK. 14 | 15 | add_library( # Sets the name of the library. 16 | audio_effect 17 | 18 | # Sets the library as a shared library. 19 | SHARED 20 | 21 | # Provides a relative path to your source file(s). 22 | audio_jni.cpp 23 | soundtouch/AAFilter.cpp 24 | soundtouch/BPMDetect.cpp 25 | soundtouch/cpu_detect_x86.cpp 26 | soundtouch/FIFOSampleBuffer.cpp 27 | soundtouch/FIRFilter.cpp 28 | soundtouch/InterpolateCubic.cpp 29 | soundtouch/InterpolateLinear.cpp 30 | soundtouch/InterpolateShannon.cpp 31 | soundtouch/mmx_optimized.cpp 32 | soundtouch/PeakFinder.cpp 33 | soundtouch/RateTransposer.cpp 34 | soundtouch/SoundTouch.cpp 35 | soundtouch/sse_optimized.cpp 36 | soundtouch/TDStretch.cpp 37 | soundtouch/WavFile.cpp) 38 | 39 | # Searches for a specified prebuilt library and stores the path as a 40 | # variable. Because CMake includes system libraries in the search path by 41 | # default, you only need to specify the name of the public NDK library 42 | # you want to add. CMake verifies that the library exists before 43 | # completing its build. 44 | 45 | find_library( # Sets the name of the path variable. 46 | log-lib 47 | 48 | # Specifies the name of the NDK library that 49 | # you want CMake to locate. 50 | log) 51 | 52 | # Specifies libraries CMake should link to your target library. You 53 | # can link multiple libraries, such as libraries you define in this 54 | # build script, prebuilt third-party libraries, or system libraries. 55 | 56 | target_link_libraries( # Specifies the target library. 57 | audio_effect 58 | # Links the target library to the log library 59 | # included in the NDK. 60 | ${log-lib}) -------------------------------------------------------------------------------- /audiolibrary/src/main/cpp/soundtouch/InterpolateCubic.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | /// 3 | /// Cubic interpolation routine. 4 | /// 5 | /// Author : Copyright (c) Olli Parviainen 6 | /// Author e-mail : oparviai 'at' iki.fi 7 | /// SoundTouch WWW: http://www.surina.net/soundtouch 8 | /// 9 | //////////////////////////////////////////////////////////////////////////////// 10 | // 11 | // License : 12 | // 13 | // SoundTouch audio processing library 14 | // Copyright (c) Olli Parviainen 15 | // 16 | // This library is free software; you can redistribute it and/or 17 | // modify it under the terms of the GNU Lesser General Public 18 | // License as published by the Free Software Foundation; either 19 | // version 2.1 of the License, or (at your option) any later version. 20 | // 21 | // This library is distributed in the hope that it will be useful, 22 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | // Lesser General Public License for more details. 25 | // 26 | // You should have received a copy of the GNU Lesser General Public 27 | // License along with this library; if not, write to the Free Software 28 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 | // 30 | //////////////////////////////////////////////////////////////////////////////// 31 | 32 | #ifndef _InterpolateCubic_H_ 33 | #define _InterpolateCubic_H_ 34 | 35 | #include "RateTransposer.h" 36 | #include "STTypes.h" 37 | 38 | namespace soundtouch 39 | { 40 | 41 | class InterpolateCubic : public TransposerBase 42 | { 43 | protected: 44 | virtual void resetRegisters(); 45 | virtual int transposeMono(SAMPLETYPE *dest, 46 | const SAMPLETYPE *src, 47 | int &srcSamples); 48 | virtual int transposeStereo(SAMPLETYPE *dest, 49 | const SAMPLETYPE *src, 50 | int &srcSamples); 51 | virtual int transposeMulti(SAMPLETYPE *dest, 52 | const SAMPLETYPE *src, 53 | int &srcSamples); 54 | 55 | double fract; 56 | 57 | public: 58 | InterpolateCubic(); 59 | 60 | int getLatency() const 61 | { 62 | return 1; 63 | } 64 | }; 65 | 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /audiolibrary/src/main/cpp/soundtouch/InterpolateShannon.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | /// 3 | /// Sample interpolation routine using 8-tap band-limited Shannon interpolation 4 | /// with kaiser window. 5 | /// 6 | /// Notice. This algorithm is remarkably much heavier than linear or cubic 7 | /// interpolation, and not remarkably better than cubic algorithm. Thus mostly 8 | /// for experimental purposes 9 | /// 10 | /// Author : Copyright (c) Olli Parviainen 11 | /// Author e-mail : oparviai 'at' iki.fi 12 | /// SoundTouch WWW: http://www.surina.net/soundtouch 13 | /// 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // 16 | // License : 17 | // 18 | // SoundTouch audio processing library 19 | // Copyright (c) Olli Parviainen 20 | // 21 | // This library is free software; you can redistribute it and/or 22 | // modify it under the terms of the GNU Lesser General Public 23 | // License as published by the Free Software Foundation; either 24 | // version 2.1 of the License, or (at your option) any later version. 25 | // 26 | // This library is distributed in the hope that it will be useful, 27 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 | // Lesser General Public License for more details. 30 | // 31 | // You should have received a copy of the GNU Lesser General Public 32 | // License along with this library; if not, write to the Free Software 33 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34 | // 35 | //////////////////////////////////////////////////////////////////////////////// 36 | 37 | #ifndef _InterpolateShannon_H_ 38 | #define _InterpolateShannon_H_ 39 | 40 | #include "RateTransposer.h" 41 | #include "STTypes.h" 42 | 43 | namespace soundtouch 44 | { 45 | 46 | class InterpolateShannon : public TransposerBase 47 | { 48 | protected: 49 | void resetRegisters(); 50 | int transposeMono(SAMPLETYPE *dest, 51 | const SAMPLETYPE *src, 52 | int &srcSamples); 53 | int transposeStereo(SAMPLETYPE *dest, 54 | const SAMPLETYPE *src, 55 | int &srcSamples); 56 | int transposeMulti(SAMPLETYPE *dest, 57 | const SAMPLETYPE *src, 58 | int &srcSamples); 59 | 60 | double fract; 61 | 62 | public: 63 | InterpolateShannon(); 64 | 65 | int getLatency() const 66 | { 67 | return 3; 68 | } 69 | }; 70 | 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /audiolibrary/src/main/cpp/soundtouch/cpu_detect.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | /// 3 | /// A header file for detecting the Intel MMX instructions set extension. 4 | /// 5 | /// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the 6 | /// routine implementations for x86 Windows, x86 gnu version and non-x86 7 | /// platforms, respectively. 8 | /// 9 | /// Author : Copyright (c) Olli Parviainen 10 | /// Author e-mail : oparviai 'at' iki.fi 11 | /// SoundTouch WWW: http://www.surina.net/soundtouch 12 | /// 13 | //////////////////////////////////////////////////////////////////////////////// 14 | // 15 | // License : 16 | // 17 | // SoundTouch audio processing library 18 | // Copyright (c) Olli Parviainen 19 | // 20 | // This library is free software; you can redistribute it and/or 21 | // modify it under the terms of the GNU Lesser General Public 22 | // License as published by the Free Software Foundation; either 23 | // version 2.1 of the License, or (at your option) any later version. 24 | // 25 | // This library is distributed in the hope that it will be useful, 26 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 | // Lesser General Public License for more details. 29 | // 30 | // You should have received a copy of the GNU Lesser General Public 31 | // License along with this library; if not, write to the Free Software 32 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 33 | // 34 | //////////////////////////////////////////////////////////////////////////////// 35 | 36 | #ifndef _CPU_DETECT_H_ 37 | #define _CPU_DETECT_H_ 38 | 39 | #include "STTypes.h" 40 | 41 | #define SUPPORT_MMX 0x0001 42 | #define SUPPORT_3DNOW 0x0002 43 | #define SUPPORT_ALTIVEC 0x0004 44 | #define SUPPORT_SSE 0x0008 45 | #define SUPPORT_SSE2 0x0010 46 | 47 | /// Checks which instruction set extensions are supported by the CPU. 48 | /// 49 | /// \return A bitmask of supported extensions, see SUPPORT_... defines. 50 | uint detectCPUextensions(void); 51 | 52 | /// Disables given set of instruction extensions. See SUPPORT_... defines. 53 | void disableExtensions(uint wDisableMask); 54 | 55 | #endif // _CPU_DETECT_H_ 56 | -------------------------------------------------------------------------------- /audiolibrary/src/main/java/com/jeffmony/audioeffect/AudioProcess.java: -------------------------------------------------------------------------------- 1 | package com.jeffmony.audioeffect; 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | /// 5 | /// Example class that invokes native SoundTouch routines through the JNI 6 | /// interface. 7 | /// 8 | /// Author : Copyright (c) Olli Parviainen 9 | /// Author e-mail : oparviai 'at' iki.fi 10 | /// WWW : http://www.surina.net 11 | /// 12 | //////////////////////////////////////////////////////////////////////////////// 13 | 14 | public final class AudioProcess 15 | { 16 | // Load the native library upon startup 17 | static { 18 | System.loadLibrary("audio_effect"); 19 | } 20 | 21 | // Native interface function that returns SoundTouch version string. 22 | // This invokes the native c++ routine defined in "soundtouch-jni.cpp". 23 | public native static String getVersionString(); 24 | 25 | private native void setTempo(long handle, float tempo); 26 | 27 | private native void setPitchSemiTones(long handle, float pitch); 28 | 29 | private native void setSpeed(long handle, float speed); 30 | 31 | private native int processFile(long handle, String inputFile, String outputFile); 32 | 33 | public native static String getErrorString(); 34 | 35 | private native static long newInstance(); 36 | 37 | private native void deleteInstance(long handle); 38 | 39 | private long mId = 0; 40 | 41 | public AudioProcess() { 42 | mId = newInstance(); 43 | } 44 | 45 | 46 | public void close() { 47 | deleteInstance(mId); 48 | mId = 0; 49 | } 50 | 51 | 52 | public void setTempo(float tempo) { 53 | setTempo(mId, tempo); 54 | } 55 | 56 | 57 | public void setPitchSemiTones(float pitch) { 58 | setPitchSemiTones(mId, pitch); 59 | } 60 | 61 | 62 | public void setSpeed(float speed) { 63 | setSpeed(mId, speed); 64 | } 65 | 66 | 67 | public int processFile(String inputFile, String outputFile) { 68 | return processFile(mId, inputFile, outputFile); 69 | } 70 | 71 | } 72 | 73 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.3.72' 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:4.1.3' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | android.enableJetifier=true 10 | android.useAndroidX=true 11 | org.gradle.jvmargs=-Xmx1536m 12 | android.injected.testOnly=false 13 | # When configured, Gradle will run in incubating parallel mode. 14 | # This option should only be used with decoupled projects. More details, visit 15 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 16 | # org.gradle.parallel=true 17 | 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Apr 03 09:58:43 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip 7 | -------------------------------------------------------------------------------- /playerLibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /playerLibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 30 6 | 7 | defaultConfig { 8 | minSdkVersion 19 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(dir: 'libs', include: ['*.jar']) 25 | 26 | api 'com.google.android.exoplayer:exoplayer-core:2.8.3' 27 | api 'com.google.android.exoplayer:exoplayer-ui:2.8.3' 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 29 | } 30 | repositories { 31 | mavenCentral() 32 | } 33 | -------------------------------------------------------------------------------- /playerLibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /playerLibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/MediaItem.java: -------------------------------------------------------------------------------- 1 | package com.video.player; 2 | 3 | public class MediaItem { 4 | private String mTitle; 5 | private String mPath; 6 | private long mDuration; 7 | private long mSize; 8 | 9 | public MediaItem(String title, String path, long duration, long size) { 10 | mTitle = title; 11 | mPath = path; 12 | mDuration = duration; 13 | mSize = size; 14 | } 15 | 16 | public String getTitle() { 17 | return mTitle; 18 | } 19 | 20 | public String getPath() { 21 | return mPath; 22 | } 23 | 24 | public long getDuration() { 25 | return mDuration; 26 | } 27 | 28 | public long getSize() { 29 | return mSize; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/MediaUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.player; 2 | 3 | import android.content.ContentResolver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.database.Cursor; 7 | import android.media.MediaMetadataRetriever; 8 | import android.net.Uri; 9 | import android.provider.MediaStore; 10 | 11 | public class MediaUtils { 12 | public static MediaItem getMediaItem(ContentResolver resolver, Intent intent) { 13 | Uri uri = intent.getData(); 14 | MediaItem mediaItem = null; 15 | Cursor cursor = resolver.query(uri, null, null, null, null); 16 | if (cursor != null) { 17 | if (cursor.moveToFirst()) { 18 | String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE)); 19 | String path = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA)); 20 | long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.DURATION)); 21 | long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.SIZE)); 22 | mediaItem = new MediaItem(title, path, duration, size); 23 | } 24 | cursor.close(); 25 | } 26 | return mediaItem; 27 | } 28 | 29 | public static long getDuration(Context context, String path) { 30 | MediaMetadataRetriever mmr = new MediaMetadataRetriever(); 31 | try { 32 | mmr.setDataSource(context, Uri.parse(path)); 33 | String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 34 | return Long.parseLong(duration); 35 | } catch (Exception e) { 36 | 37 | } finally { 38 | if (mmr != null) { 39 | mmr.release(); 40 | } 41 | } 42 | 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/ToastExt.kt: -------------------------------------------------------------------------------- 1 | package com.video.player 2 | 3 | import android.content.Context 4 | import android.text.TextUtils 5 | import android.view.Gravity 6 | import android.view.View 7 | import android.widget.TextView 8 | import android.widget.Toast 9 | import com.spx.library.R 10 | 11 | var toast: Toast? = null 12 | 13 | fun cancelToast() { 14 | toast?.run { 15 | cancel() 16 | toast = null 17 | } 18 | } 19 | 20 | /** 21 | * 通用的toast 22 | */ 23 | fun Context.showToast(desc: String) { 24 | 25 | toast = if (toast == null) { 26 | Toast(this) 27 | } else { 28 | toast!!.cancel() 29 | Toast(this) 30 | } 31 | 32 | val view = View.inflate(this, R.layout.baseres_toast_layout, null) 33 | 34 | val messageText = view.findViewById(R.id.message) 35 | // ViewCompat.setElevation(messageText, 2.0f) 36 | if (!TextUtils.isEmpty(desc)) { 37 | messageText.text = desc 38 | } 39 | toast!!.duration = Toast.LENGTH_SHORT 40 | toast!!.view = view 41 | toast!!.setGravity(Gravity.TOP, 0, this.resources.displayMetrics.heightPixels / 2) 42 | toast!!.show() 43 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/VideoItem.kt: -------------------------------------------------------------------------------- 1 | package com.video.player 2 | 3 | class VideoItem(val title: String, val path: String, val durationSec: Int, val size: Long) -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/ext.kt: -------------------------------------------------------------------------------- 1 | package com.video.player 2 | 3 | import android.app.Activity 4 | import android.util.Log 5 | 6 | fun Activity.log(message:String){ 7 | Log.d(this.javaClass.simpleName, message) 8 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/player/VideoPlayTimeController.kt: -------------------------------------------------------------------------------- 1 | package com.video.player.player 2 | 3 | import android.os.Handler 4 | 5 | class VideoPlayTimeController(val player: VideoPlayer) { 6 | 7 | var handler: Handler = Handler() 8 | var startTime: Long = 0 9 | var endTime: Long = 0 10 | fun setPlayTimeRange(start: Long, end: Long) { 11 | startTime = start 12 | endTime = end 13 | } 14 | 15 | fun start() { 16 | handler.postDelayed({ check() }, 500) 17 | } 18 | 19 | fun check() { 20 | 21 | if (endTime == 0L || endTime < startTime) { 22 | endTime = player.getDuration().toLong() 23 | } 24 | 25 | if (player.getPlayerCurrentPosition() > endTime) { 26 | player.seekToPosition(startTime) 27 | player.startPlayer() 28 | } else if (player.getPlayerCurrentPosition() < startTime) { 29 | player.seekToPosition(startTime) 30 | player.startPlayer() 31 | } 32 | handler.postDelayed({ check() }, 16) 33 | } 34 | 35 | fun stop() { 36 | handler.removeCallbacksAndMessages(null) 37 | } 38 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/player/VideoPlayer.kt: -------------------------------------------------------------------------------- 1 | package com.video.player.player 2 | 3 | import android.content.Context 4 | 5 | interface VideoPlayer { 6 | 7 | fun setupPlayer(context: Context, mediaPath:String) 8 | 9 | fun initPlayer() 10 | 11 | fun pausePlayer() 12 | 13 | fun startPlayer() 14 | 15 | fun seekToPosition(position: Long) 16 | 17 | fun getPlayerCurrentPosition(): Int 18 | fun getDuration():Int 19 | 20 | fun setPlaySpeed(speed:Float) 21 | 22 | fun enableFramePreviewMode() 23 | fun releasePlayer() 24 | fun isPlaying(): Boolean 25 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/player/VideoPlayerOfExoPlayer.kt: -------------------------------------------------------------------------------- 1 | package com.video.player.player 2 | 3 | import android.content.Context 4 | import android.util.Log 5 | import com.google.android.exoplayer2.Player 6 | import com.google.android.exoplayer2.SimpleExoPlayer 7 | import com.google.android.exoplayer2.ui.AspectRatioFrameLayout 8 | import com.google.android.exoplayer2.ui.PlayerView 9 | import com.google.android.exoplayer2.PlaybackParameters 10 | import com.google.android.exoplayer2.Player.STATE_READY 11 | 12 | class VideoPlayerOfExoPlayer(val playerView: PlayerView) : VideoPlayer { 13 | 14 | companion object { 15 | val TAG = "VideoPlayerOfExoPlayer" 16 | val PREVIEW_MODE_MS_LONG = 250 17 | val PREVIEW_MODE_MS_SHORT = 100 18 | } 19 | 20 | var lastSeekingPosition = 0L 21 | var previewModeTimeMs = PREVIEW_MODE_MS_LONG 22 | var exoPlayer: SimpleExoPlayer? = null 23 | 24 | override fun enableFramePreviewMode() { 25 | previewModeTimeMs = PREVIEW_MODE_MS_SHORT 26 | } 27 | 28 | var videoListener = object : SimpleExoPlayer.VideoListener { 29 | override fun onVideoSizeChanged(width: Int, height: Int, _un: Int, _p: Float) { 30 | if (width < height) { 31 | return 32 | } 33 | playerView?.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT) 34 | } 35 | 36 | override fun onRenderedFirstFrame() { 37 | } 38 | 39 | } 40 | 41 | var listener: Player.DefaultEventListener = object : Player.DefaultEventListener() { 42 | override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) { 43 | Log.d(TAG, "player state $playbackState") 44 | } 45 | } 46 | 47 | override fun setupPlayer(context: Context, mediaPath: String) { 48 | exoPlayer = com.video.player.player.initPlayer(context, mediaPath, playerView!!, listener) 49 | startPlayer() 50 | } 51 | 52 | override fun initPlayer() { 53 | 54 | } 55 | 56 | override fun pausePlayer() { 57 | exoPlayer?.playWhenReady = false 58 | } 59 | 60 | override fun startPlayer() { 61 | exoPlayer?.playWhenReady = true 62 | } 63 | 64 | override fun seekToPosition(position: Long) { 65 | if (Math.abs(position - lastSeekingPosition) < previewModeTimeMs) { 66 | return 67 | } 68 | 69 | exoPlayer?.seekTo(position) 70 | exoPlayer?.playWhenReady = true 71 | lastSeekingPosition = position 72 | } 73 | 74 | override fun getPlayerCurrentPosition(): Int { 75 | return exoPlayer?.currentPosition?.toInt() ?: 0 76 | } 77 | 78 | override fun setPlaySpeed(speed: Float) { 79 | val param = PlaybackParameters(speed) 80 | exoPlayer?.setPlaybackParameters(param) 81 | } 82 | 83 | override fun releasePlayer() { 84 | exoPlayer?.release() 85 | exoPlayer= null 86 | } 87 | 88 | override fun isPlaying(): Boolean { 89 | return exoPlayer?.playWhenReady == true && exoPlayer?.playbackState == STATE_READY 90 | } 91 | 92 | override fun getDuration(): Int { 93 | return (exoPlayer?.duration?:0).toInt() 94 | } 95 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/player/VideoPlayerOfMediaPlayer.kt: -------------------------------------------------------------------------------- 1 | package com.video.player.player 2 | 3 | import android.annotation.TargetApi 4 | import android.content.Context 5 | import android.media.MediaPlayer 6 | import android.os.Build 7 | import android.view.SurfaceHolder 8 | import android.view.SurfaceView 9 | 10 | class VideoPlayerOfMediaPlayer(val surfaceView: SurfaceView) : VideoPlayer { 11 | 12 | 13 | var mediaPlayer: MediaPlayer? = null 14 | var surfaceHolder: SurfaceHolder? = null 15 | 16 | override fun setupPlayer(context: Context, mediaPath: String) { 17 | mediaPlayer?.setDataSource(mediaPath) 18 | mediaPlayer?.prepare() 19 | mediaPlayer?.setOnPreparedListener { 20 | mediaPlayer!!.start() 21 | mediaPlayer!!.isLooping = true 22 | } 23 | } 24 | 25 | override fun initPlayer() { 26 | mediaPlayer = MediaPlayer() 27 | val holder = surfaceView.holder 28 | if (surfaceHolder != null) { 29 | mediaPlayer!!.setDisplay(surfaceHolder) 30 | } 31 | holder.addCallback(object : SurfaceHolder.Callback { 32 | override fun surfaceDestroyed(holder: SurfaceHolder) { 33 | } 34 | 35 | override fun surfaceCreated(holder: SurfaceHolder) { 36 | } 37 | 38 | override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { 39 | mediaPlayer!!.setDisplay(holder) 40 | surfaceHolder = holder 41 | } 42 | 43 | }) 44 | 45 | } 46 | 47 | override fun pausePlayer() { 48 | mediaPlayer?.pause() 49 | } 50 | 51 | override fun startPlayer() { 52 | mediaPlayer?.start() 53 | } 54 | 55 | override fun seekToPosition(position: Long) { 56 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 57 | mediaPlayer?.seekTo(position, MediaPlayer.SEEK_CLOSEST) 58 | } else { 59 | mediaPlayer?.seekTo(position.toInt()) 60 | } 61 | } 62 | 63 | override fun getPlayerCurrentPosition(): Int { 64 | return mediaPlayer?.currentPosition ?: 0 65 | } 66 | 67 | override fun setPlaySpeed(speed: Float) { 68 | setMediaPlayerSpeed(speed) 69 | } 70 | 71 | @TargetApi(Build.VERSION_CODES.M) 72 | private fun setMediaPlayerSpeed(speed: Float) { 73 | if (mediaPlayer!!.isPlaying()) { 74 | mediaPlayer!!.setPlaybackParams(mediaPlayer!!.getPlaybackParams().setSpeed(speed)) 75 | mediaPlayer!!.start() 76 | } else { 77 | mediaPlayer!!.setPlaybackParams(mediaPlayer!!.getPlaybackParams().setSpeed(speed)) 78 | mediaPlayer!!.pause() 79 | } 80 | } 81 | 82 | override fun enableFramePreviewMode() { 83 | 84 | } 85 | 86 | override fun releasePlayer() { 87 | mediaPlayer?.stop() 88 | mediaPlayer?.reset() 89 | } 90 | 91 | override fun isPlaying(): Boolean { 92 | return mediaPlayer?.isPlaying ?: false 93 | } 94 | override fun getDuration(): Int { 95 | return mediaPlayer?.duration?:0 96 | } 97 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/player/player.kt: -------------------------------------------------------------------------------- 1 | package com.video.player.player 2 | 3 | import android.content.Context 4 | import android.net.Uri 5 | import android.view.View 6 | import com.google.android.exoplayer2.* 7 | import com.google.android.exoplayer2.source.ExtractorMediaSource 8 | import com.google.android.exoplayer2.trackselection.DefaultTrackSelector 9 | import com.google.android.exoplayer2.ui.PlayerView 10 | import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory 11 | 12 | 13 | fun initPlayer(context: Context, videoUrl:String, playerView: PlayerView, 14 | listener: Player.EventListener ):SimpleExoPlayer { 15 | var TAG ="initPlayer" 16 | val defaultSourceFactory = DefaultDataSourceFactory(context,"luedong") 17 | 18 | var loadControl = MyLoadControl() 19 | 20 | var player = ExoPlayerFactory.newSimpleInstance( DefaultRenderersFactory(context), 21 | DefaultTrackSelector(),DefaultLoadControl(),null ) 22 | 23 | playerView.visibility = View.VISIBLE 24 | playerView.player = player 25 | player!!.addListener(listener) 26 | 27 | player!!.repeatMode = Player.REPEAT_MODE_ALL 28 | player!!.playWhenReady = true 29 | 30 | var mVideoSource = ExtractorMediaSource.Factory(defaultSourceFactory).createMediaSource(Uri.parse(videoUrl)!!) 31 | 32 | if (player != null) { 33 | player!!.prepare(mVideoSource) 34 | } 35 | 36 | return player 37 | } 38 | 39 | fun initPlayer(context: Context, videoUrl: String, 40 | listener: Player.EventListener): SimpleExoPlayer { 41 | val defaultSourceFactory = DefaultDataSourceFactory(context, "luedong") 42 | 43 | var player = ExoPlayerFactory.newSimpleInstance(context, DefaultTrackSelector()) 44 | 45 | player!!.addListener(listener) 46 | 47 | player!!.repeatMode = Player.REPEAT_MODE_ALL 48 | player!!.playWhenReady = true 49 | 50 | var mVideoSource = ExtractorMediaSource.Factory(defaultSourceFactory).createMediaSource(Uri.parse(videoUrl)!!) 51 | 52 | if (player != null) { 53 | player!!.prepare(mVideoSource) 54 | } 55 | 56 | return player 57 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/java/com/video/player/util/RawResourceReader.java: -------------------------------------------------------------------------------- 1 | package com.video.player.util; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | 11 | public class RawResourceReader 12 | { 13 | public static String readTextFileFromRawResource(final Context context, 14 | final int resourceId) 15 | { 16 | final InputStream inputStream = context.getResources().openRawResource( 17 | resourceId); 18 | final InputStreamReader inputStreamReader = new InputStreamReader( 19 | inputStream); 20 | final BufferedReader bufferedReader = new BufferedReader( 21 | inputStreamReader); 22 | 23 | String nextLine; 24 | final StringBuilder body = new StringBuilder(); 25 | 26 | try 27 | { 28 | while ((nextLine = bufferedReader.readLine()) != null) 29 | { 30 | body.append(nextLine); 31 | body.append('\n'); 32 | } 33 | } 34 | catch (IOException e) 35 | { 36 | return null; 37 | } 38 | 39 | return body.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/layout/baseres_toast_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/def_vertext.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 aPosition; 2 | attribute vec4 aTextureCoord; 3 | varying highp vec2 textureCoordinate; 4 | void main() { 5 | gl_Position = aPosition; 6 | textureCoordinate = aTextureCoord.xy; 7 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_canying.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | varying vec2 textureCoordinate; 3 | uniform sampler2D inputTexture; 4 | uniform sampler2D uTexture1; 5 | uniform sampler2D uTexture2; 6 | vec4 lookup(in vec4 textureColor) 7 | { 8 | mediump float blueColor = textureColor.b * 63.0; 9 | mediump vec2 quad1; quad1.y = floor(floor(blueColor) / 8.0); 10 | quad1.x = floor(blueColor) - (quad1.y * 8.0); 11 | mediump vec2 quad2; quad2.y = floor(ceil(blueColor) / 8.0); 12 | quad2.x = ceil(blueColor) - (quad2.y * 8.0); 13 | highp vec2 texPos1; 14 | texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); 15 | texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); 16 | texPos1.y = 1.0-texPos1.y; 17 | highp vec2 texPos2; 18 | texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r); 19 | texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g); 20 | texPos2.y = 1.0-texPos2.y; lowp vec4 newColor1 = texture2D(uTexture2, texPos1); 21 | lowp vec4 newColor2 = texture2D(uTexture2, texPos2); 22 | lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor)); 23 | return newColor; 24 | } 25 | 26 | void main() 27 | { 28 | vec4 lastFrame = texture2D(uTexture1,textureCoordinate); 29 | vec4 currentFrame = lookup(texture2D(inputTexture,textureCoordinate)); 30 | gl_FragColor = vec4(0.95 * lastFrame.r + 0.05* currentFrame.r,currentFrame.g * 0.2 + lastFrame.g * 0.8, currentFrame.b,1.0); 31 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_flash.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision mediump float; 3 | varying vec2 textureCoordinate; 4 | uniform sampler2D inputTexture; 5 | //修改这个值,可以控制曝光的程度 6 | uniform float uAdditionalColor; 7 | void main() 8 | { 9 | vec4 color = texture2D(inputTexture,textureCoordinate.xy); 10 | gl_FragColor = vec4(color.r + uAdditionalColor,color.g + uAdditionalColor,color.b + uAdditionalColor,color.a); 11 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_itch.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision highp float; 3 | varying vec2 textureCoordinate; 4 | uniform sampler2D inputTexture; 5 | //这是个二阶向量,x是横向偏移的值,y是阈值 6 | uniform vec2 uScanLineJitter; 7 | //颜色偏移的值 8 | uniform float uColorDrift; 9 | //随机函数 10 | float nrand(in float x, in float y) 11 | { 12 | return fract(sin(dot(vec2(x, y), vec2(12.9898, 78.233))) * 43758.5453); 13 | } 14 | 15 | void main() 16 | { 17 | float u = textureCoordinate.x; 18 | float v = textureCoordinate.y; 19 | float jitter = nrand(v,0.0) * 2.0 - 1.0; 20 | float drift = uColorDrift; 21 | float offsetParam = step(uScanLineJitter.y,abs(jitter)); 22 | jitter = jitter * offsetParam * uScanLineJitter.x; 23 | vec4 color1 = texture2D(inputTexture,fract(vec2( u + jitter,v))); 24 | vec4 color2 = texture2D(inputTexture,fract(vec2(u + jitter + v*drift ,v))); 25 | gl_FragColor = vec4(color1.r,color2.g,color1.b,1.0); 26 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_scale.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision mediump float; 3 | varying vec2 textureCoordinate; 4 | uniform sampler2D inputTexture; 5 | uniform float scale; 6 | void main() { 7 | vec2 uv = textureCoordinate.xy; 8 | // 将纹理坐标中心转成(0.0, 0.0)再做缩放 9 | vec2 center = vec2(0.5, 0.5); 10 | uv -= center; uv = uv / scale; 11 | uv += center; 12 | gl_FragColor = texture2D(inputTexture, uv); 13 | } 14 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_shake.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | varying vec2 textureCoordinate; 3 | uniform sampler2D inputTexture; 4 | uniform float scale; 5 | void main() { 6 | vec2 uv = textureCoordinate.xy; 7 | vec2 scaleCoordinate = vec2((scale - 1.0) * 0.5 + uv.x / scale , (scale - 1.0) * 0.5 + uv.y / scale); 8 | vec4 smoothColor = texture2D(inputTexture, scaleCoordinate); 9 | // 计算红色通道偏移值 10 | vec4 shiftRedColor = texture2D(inputTexture, scaleCoordinate + vec2(-0.1 * (scale - 1.0), - 0.1 *(scale - 1.0))); 11 | // 计算绿色通道偏移值 12 | vec4 shiftGreenColor = texture2D(inputTexture, scaleCoordinate + vec2(-0.075 * (scale - 1.0), - 0.075 *(scale - 1.0))); 13 | // 计算蓝色偏移值 14 | vec4 shiftBlueColor = texture2D(inputTexture, scaleCoordinate + vec2(-0.05 * (scale - 1.0), - 0.05 *(scale - 1.0))); 15 | vec3 resultColor = vec3(shiftRedColor.r, shiftGreenColor.g, shiftBlueColor.b); 16 | gl_FragColor = vec4(resultColor, smoothColor.a); 17 | } 18 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_sharder.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision mediump float; 3 | uniform samplerExternalOES texture; 4 | varying vec2 v_TexCoordinate; 5 | 6 | void main () { 7 | vec4 color = texture2D(texture, v_TexCoordinate); 8 | gl_FragColor = color; 9 | } -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_soulout.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | varying vec2 textureCoordinate; 3 | uniform sampler2D inputTexture; 4 | uniform float scale; 5 | void main() 6 | { 7 | vec2 uv = textureCoordinate.xy; 8 | // 输入纹理 9 | vec4 sourceColor = texture2D(inputTexture, fract(uv)); 10 | // 将纹理坐标中心转成(0.0, 0.0)再做缩放 11 | vec2 center = vec2(0.5, 0.5); 12 | uv -= center; 13 | uv = uv / scale; 14 | uv += center; 15 | // 缩放纹理 16 | vec4 scaleColor = texture2D(inputTexture, fract(uv)); 17 | // 线性混合 18 | gl_FragColor = mix(sourceColor, scaleColor, 0.5 * (0.6 - fract(scale))); 19 | } 20 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/fragment_split4.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_EGL_image_external : require 2 | precision highp float; 3 | varying highp vec2 textureCoordinate; 4 | uniform sampler2D inputTexture; 5 | void main() { 6 | vec2 uv = textureCoordinate; 7 | if (uv.x <= 0.5) { uv.x = uv.x * 2.0; } 8 | else { uv.x = (uv.x - 0.5) * 2.0; } 9 | if (uv.y <= 0.5) { uv.y = uv.y * 2.0; } 10 | else { uv.y = (uv.y - 0.5) * 2.0; } 11 | gl_FragColor = texture2D(inputTexture, fract(uv)); 12 | } 13 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/raw/vetext_sharder.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 vPosition; 2 | attribute vec4 vTexCoordinate; 3 | uniform mat4 textureTransform; 4 | varying vec2 v_TexCoordinate; 5 | 6 | void main () { 7 | v_TexCoordinate = (textureTransform * vTexCoordinate).xy; 8 | gl_Position = vPosition; 9 | } 10 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #cc000000 4 | -------------------------------------------------------------------------------- /playerLibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Library 3 | 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':audiolibrary' 2 | include ':app', ':playerLibrary', ':videoEditSdk' 3 | -------------------------------------------------------------------------------- /videoEditSdk/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /.cxx 3 | -------------------------------------------------------------------------------- /videoEditSdk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | 3 | #cpp文件 4 | add_library(MagicBeautify 5 | SHARED 6 | src/main/jni/MagicJni.cpp) 7 | 8 | #lib引用 9 | find_library(log-lib log) 10 | find_library(jnigraphics-lib jnigraphics) 11 | find_library(GLESv2-lib GLESv2) 12 | 13 | #链接lib 14 | target_link_libraries(MagicBeautify 15 | ${log-lib} 16 | ${jnigraphics-lib} 17 | ${GLESv2-lib}) -------------------------------------------------------------------------------- /videoEditSdk/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 30 6 | 7 | defaultConfig { 8 | minSdkVersion 19 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "-frtti -fexceptions" 16 | } 17 | } 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | 27 | externalNativeBuild { 28 | cmake { 29 | path 'CMakeLists.txt' 30 | } 31 | } 32 | 33 | 34 | lintOptions { 35 | abortOnError false 36 | } 37 | } 38 | 39 | dependencies { 40 | implementation fileTree(dir: 'libs', include: ['*.jar']) 41 | 42 | implementation 'androidx.appcompat:appcompat:1.0.0' 43 | implementation project(path: ':playerLibrary') 44 | implementation project(path: ':audiolibrary') 45 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 46 | } 47 | repositories { 48 | mavenCentral() 49 | } 50 | -------------------------------------------------------------------------------- /videoEditSdk/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_fennen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_fennen.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_huaijiu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_huaijiu.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_landiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_landiao.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_langman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_langman.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_qingliang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_qingliang.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_qingxin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_qingxin.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_rixi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_rixi.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_weimei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_weimei.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/filter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/filter_white.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/lookup_vertigo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/lookup_vertigo.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/skin_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/skin_gray.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/assets/filters/skin_lookup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/assets/filters/skin_lookup.png -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/audio/IAudioComposer.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.audio; 2 | 3 | /** 4 | * Created by sudamasayuki2 on 2018/02/24. 5 | */ 6 | 7 | public interface IAudioComposer { 8 | 9 | void setup(); 10 | 11 | boolean stepPipeline(); 12 | 13 | long getWrittenPresentationTimeUs(); 14 | 15 | boolean isFinished(); 16 | 17 | void release(); 18 | } 19 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlBulgeDistortionComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.utils.GLESUtils; 6 | 7 | /** 8 | * Created by sudamasayuki on 2018/01/06. 9 | */ 10 | 11 | public class GlBulgeDistortionComposeFilter extends GlComposeFilter { 12 | 13 | private static final String FRAGMENT_SHADER = 14 | "#extension GL_OES_EGL_image_external : require\n" + 15 | "precision mediump float;" + 16 | 17 | "varying highp vec2 vTextureCoord;" + 18 | "uniform samplerExternalOES sTexture;" + 19 | 20 | "uniform highp vec2 center;" + 21 | "uniform highp float radius;" + 22 | "uniform highp float scale;" + 23 | 24 | "void main() {" + 25 | "highp vec2 textureCoordinateToUse = vTextureCoord;" + 26 | "highp float dist = distance(center, vTextureCoord);" + 27 | "textureCoordinateToUse -= center;" + 28 | "if (dist < radius) {" + 29 | "highp float percent = 1.0 - ((radius - dist) / radius) * scale;" + 30 | "percent = percent * percent;" + 31 | "textureCoordinateToUse = textureCoordinateToUse * percent;" + 32 | "}" + 33 | "textureCoordinateToUse += center;" + 34 | 35 | "gl_FragColor = texture2D(sTexture, textureCoordinateToUse);" + 36 | "}"; 37 | 38 | private float centerX = 0.5f; 39 | private float centerY = 0.5f; 40 | private float radius = 0.25f; 41 | private float scale = 0.5f; 42 | 43 | public GlBulgeDistortionComposeFilter() { 44 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 45 | } 46 | 47 | public float getCenterX() { 48 | return centerX; 49 | } 50 | 51 | public void setCenterX(final float centerX) { 52 | this.centerX = centerX; 53 | } 54 | 55 | public float getCenterY() { 56 | return centerY; 57 | } 58 | 59 | public void setCenterY(final float centerY) { 60 | this.centerY = centerY; 61 | } 62 | 63 | public float getRadius() { 64 | return radius; 65 | } 66 | 67 | public void setRadius(final float radius) { 68 | this.radius = radius; 69 | } 70 | 71 | public float getScale() { 72 | return scale; 73 | } 74 | 75 | public void setScale(final float scale) { 76 | this.scale = scale; 77 | } 78 | 79 | ////////////////////////////////////////////////////////////////////////// 80 | 81 | @Override 82 | public void onDraw() { 83 | GLES20.glUniform2f(getHandle("center"), centerX, centerY); 84 | GLES20.glUniform1f(getHandle("radius"), radius); 85 | GLES20.glUniform1f(getHandle("scale"), scale); 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlCGAColorspaceComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import com.video.process.utils.GLESUtils; 4 | 5 | /** 6 | * Created by sudamasayuki on 2018/01/06. 7 | */ 8 | 9 | public class GlCGAColorspaceComposeFilter extends GlComposeFilter { 10 | 11 | private static final String FRAGMENT_SHADER = 12 | "#extension GL_OES_EGL_image_external : require\n" + 13 | "precision mediump float;" + 14 | 15 | "varying vec2 vTextureCoord;" + 16 | "uniform samplerExternalOES sTexture;\n" + 17 | 18 | "void main() {" + 19 | "highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);" + 20 | 21 | "highp vec2 samplePos = vTextureCoord - mod(vTextureCoord, sampleDivisor);" + 22 | "highp vec4 color = texture2D(sTexture, samplePos);" + 23 | 24 | "mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);" + 25 | "mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);" + 26 | "mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);" + 27 | "mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);" + 28 | 29 | "mediump vec4 endColor;" + 30 | "highp float blackDistance = distance(color, colorBlack);" + 31 | "highp float whiteDistance = distance(color, colorWhite);" + 32 | "highp float magentaDistance = distance(color, colorMagenta);" + 33 | "highp float cyanDistance = distance(color, colorCyan);" + 34 | 35 | "mediump vec4 finalColor;" + 36 | 37 | "highp float colorDistance = min(magentaDistance, cyanDistance);" + 38 | "colorDistance = min(colorDistance, whiteDistance);" + 39 | "colorDistance = min(colorDistance, blackDistance);" + 40 | 41 | "if (colorDistance == blackDistance) {" + 42 | "finalColor = colorBlack;" + 43 | "} else if (colorDistance == whiteDistance) {" + 44 | "finalColor = colorWhite;" + 45 | "} else if (colorDistance == cyanDistance) {" + 46 | "finalColor = colorCyan;" + 47 | "} else {" + 48 | "finalColor = colorMagenta;" + 49 | "}" + 50 | 51 | "gl_FragColor = finalColor;" + 52 | "}"; 53 | 54 | 55 | public GlCGAColorspaceComposeFilter() { 56 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 57 | } 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlGrayScaleComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import com.video.process.utils.GLESUtils; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/11/14. 7 | */ 8 | 9 | public class GlGrayScaleComposeFilter extends GlComposeFilter { 10 | private static final String FRAGMENT_SHADER = 11 | "#extension GL_OES_EGL_image_external : require\n" + 12 | "precision mediump float;\n" + 13 | "varying vec2 vTextureCoord;\n" + 14 | "uniform samplerExternalOES sTexture;\n" + 15 | "const highp vec3 weight = vec3(0.2125, 0.7154, 0.0721);\n" + 16 | "void main() {\n" + 17 | "float luminance = dot(texture2D(sTexture, vTextureCoord).rgb, weight);\n" + 18 | "gl_FragColor = vec4(vec3(luminance), 1.0);\n" + 19 | "}"; 20 | 21 | public GlGrayScaleComposeFilter() { 22 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlHazeComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.utils.GLESUtils; 6 | 7 | /** 8 | * Created by sudamasayuki on 2018/01/06. 9 | */ 10 | 11 | public class GlHazeComposeFilter extends GlComposeFilter { 12 | 13 | private static final String FRAGMENT_SHADER = 14 | "#extension GL_OES_EGL_image_external : require\n" + 15 | "precision mediump float;" + 16 | "varying vec2 vTextureCoord;" + 17 | "uniform samplerExternalOES sTexture;\n" + 18 | "uniform lowp float distance;" + 19 | "uniform highp float slope;" + 20 | 21 | "void main() {" + 22 | "highp vec4 color = vec4(1.0);" + 23 | 24 | "highp float d = vTextureCoord.y * slope + distance;" + 25 | 26 | "highp vec4 c = texture2D(sTexture, vTextureCoord);" + 27 | "c = (c - d * color) / (1.0 -d);" + 28 | "gl_FragColor = c;" + // consider using premultiply(c); 29 | "}"; 30 | 31 | private float distance = 0.2f; 32 | private float slope = 0.0f; 33 | 34 | public GlHazeComposeFilter() { 35 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 36 | } 37 | 38 | public float getDistance() { 39 | return distance; 40 | } 41 | 42 | public void setDistance(final float distance) { 43 | this.distance = distance; 44 | } 45 | 46 | public float getSlope() { 47 | return slope; 48 | } 49 | 50 | public void setSlope(final float slope) { 51 | this.slope = slope; 52 | } 53 | 54 | @Override 55 | public void onDraw() { 56 | GLES20.glUniform1f(getHandle("distance"), distance); 57 | GLES20.glUniform1f(getHandle("slope"), slope); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlInvertComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import com.video.process.utils.GLESUtils; 4 | 5 | /** 6 | * Created by sudamasayuki on 2018/01/06. 7 | */ 8 | 9 | public class GlInvertComposeFilter extends GlComposeFilter { 10 | private static final String FRAGMENT_SHADER = 11 | "#extension GL_OES_EGL_image_external : require\n" + 12 | "precision mediump float;" + 13 | "varying vec2 vTextureCoord;" + 14 | "uniform samplerExternalOES sTexture;\n" + 15 | "void main() {" + 16 | "lowp vec4 color = texture2D(sTexture, vTextureCoord);" + 17 | "gl_FragColor = vec4((1.0 - color.rgb), color.w);" + 18 | "}"; 19 | 20 | public GlInvertComposeFilter() { 21 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlMonochromeComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.utils.GLESUtils; 6 | 7 | /** 8 | * Created by sudamasayuki on 2018/01/06. 9 | */ 10 | 11 | public class GlMonochromeComposeFilter extends GlComposeFilter { 12 | 13 | private static final String FRAGMENT_SHADER = 14 | "#extension GL_OES_EGL_image_external : require\n" + 15 | "precision lowp float;" + 16 | 17 | "varying vec2 vTextureCoord;" + 18 | "uniform samplerExternalOES sTexture;\n" + 19 | 20 | "uniform float intensity;" + 21 | 22 | "const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);" + 23 | "const mediump vec3 filterColor = vec3(0.6, 0.45, 0.3);" + 24 | 25 | "void main() {" + 26 | 27 | "lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);" + 28 | "float luminance = dot(textureColor.rgb, luminanceWeighting);" + 29 | 30 | "lowp vec4 desat = vec4(vec3(luminance), 1.0);" + 31 | 32 | "lowp vec4 outputColor = vec4(" + 33 | "(desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r)))," + 34 | "(desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g)))," + 35 | "(desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b)))," + 36 | "1.0" + 37 | ");" + 38 | 39 | "gl_FragColor = vec4(mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a);" + 40 | "}"; 41 | 42 | private float intensity = 1.0f; 43 | 44 | public GlMonochromeComposeFilter() { 45 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 46 | } 47 | 48 | public float getIntensity() { 49 | return intensity; 50 | } 51 | 52 | public void setIntensity(float intensity) { 53 | this.intensity = intensity; 54 | } 55 | 56 | @Override 57 | public void onDraw() { 58 | GLES20.glUniform1f(getHandle("intensity"), intensity); 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlSepiaComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import com.video.process.utils.GLESUtils; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/11/14. 7 | */ 8 | 9 | public class GlSepiaComposeFilter extends GlComposeFilter { 10 | private static final String FRAGMENT_SHADER = 11 | "#extension GL_OES_EGL_image_external : require\n" + 12 | "precision mediump float;\n" + 13 | "varying vec2 vTextureCoord;\n" + 14 | "uniform samplerExternalOES sTexture;\n" + 15 | "void main() {\n" + 16 | " vec4 fragColor = texture2D(sTexture, vTextureCoord);\n" + 17 | " gl_FragColor.r = dot(fragColor.rgb, vec3(.393, .769, .189));\n" + 18 | " gl_FragColor.g = dot(fragColor.rgb, vec3(.349, .686, .168));\n" + 19 | " gl_FragColor.b = dot(fragColor.rgb, vec3(.272, .534, .131));\n" + 20 | "}"; 21 | 22 | public GlSepiaComposeFilter() { 23 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlSphereRefractionComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.utils.GLESUtils; 6 | 7 | /** 8 | * Created by sudamasayuki on 2018/01/07. 9 | */ 10 | 11 | public class GlSphereRefractionComposeFilter extends GlComposeFilter { 12 | 13 | private static final String FRAGMENT_SHADER = 14 | "#extension GL_OES_EGL_image_external : require\n" + 15 | "precision mediump float;" + 16 | 17 | "varying vec2 vTextureCoord;" + 18 | "uniform samplerExternalOES sTexture;\n" + 19 | "uniform highp vec2 center;" + 20 | "uniform highp float radius;" + 21 | "uniform highp float aspectRatio;" + 22 | "uniform highp float refractiveIndex;" + 23 | 24 | "void main() {" + 25 | "highp vec2 textureCoordinateToUse = vec2(vTextureCoord.x, (vTextureCoord.y * aspectRatio + 0.5 - 0.5 * aspectRatio));" + 26 | "highp float distanceFromCenter = distance(center, textureCoordinateToUse);" + 27 | "lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);" + 28 | 29 | "distanceFromCenter = distanceFromCenter / radius;" + 30 | 31 | "highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);" + 32 | "highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));" + 33 | 34 | "highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);" + 35 | 36 | "gl_FragColor = texture2D(sTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;" + 37 | "}"; 38 | 39 | private float centerX = 0.5f; 40 | private float centerY = 0.5f; 41 | private float radius = 0.5f; 42 | private float aspectRatio = 1.0f; 43 | private float refractiveIndex = 0.71f; 44 | 45 | public GlSphereRefractionComposeFilter() { 46 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 47 | } 48 | 49 | public void setCenterX(float centerX) { 50 | this.centerX = centerX; 51 | } 52 | 53 | public void setCenterY(float centerY) { 54 | this.centerY = centerY; 55 | } 56 | 57 | public void setRadius(float radius) { 58 | this.radius = radius; 59 | } 60 | 61 | public void setAspectRatio(float aspectRatio) { 62 | this.aspectRatio = aspectRatio; 63 | } 64 | 65 | public void setRefractiveIndex(float refractiveIndex) { 66 | this.refractiveIndex = refractiveIndex; 67 | } 68 | 69 | ////////////////////////////////////////////////////////////////////////// 70 | 71 | @Override 72 | public void onDraw() { 73 | GLES20.glUniform2f(getHandle("center"), centerX, centerY); 74 | GLES20.glUniform1f(getHandle("radius"), radius); 75 | GLES20.glUniform1f(getHandle("aspectRatio"), aspectRatio); 76 | GLES20.glUniform1f(getHandle("refractiveIndex"), refractiveIndex); 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlVignetteComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.utils.GLESUtils; 6 | 7 | /** 8 | * Created by sudamasayuki on 2018/01/07. 9 | */ 10 | 11 | public class GlVignetteComposeFilter extends GlComposeFilter { 12 | 13 | private static final String FRAGMENT_SHADER = 14 | "#extension GL_OES_EGL_image_external : require\n" + 15 | "precision mediump float;" + 16 | 17 | "varying vec2 vTextureCoord;" + 18 | "uniform samplerExternalOES sTexture;\n" + 19 | 20 | "uniform lowp vec2 vignetteCenter;" + 21 | "uniform highp float vignetteStart;" + 22 | "uniform highp float vignetteEnd;" + 23 | 24 | "void main() {" + 25 | "lowp vec3 rgb = texture2D(sTexture, vTextureCoord).rgb;" + 26 | "lowp float d = distance(vTextureCoord, vec2(vignetteCenter.x, vignetteCenter.y));" + 27 | "lowp float percent = smoothstep(vignetteStart, vignetteEnd, d);" + 28 | "gl_FragColor = vec4(mix(rgb.x, 0.0, percent), mix(rgb.y, 0.0, percent), mix(rgb.z, 0.0, percent), 1.0);" + 29 | "}"; 30 | 31 | private float vignetteCenterX = 0.5f; 32 | private float vignetteCenterY = 0.5f; 33 | private float vignetteStart = 0.2f; 34 | private float vignetteEnd = 0.85f; 35 | 36 | public GlVignetteComposeFilter() { 37 | super(GLESUtils.DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 38 | } 39 | 40 | 41 | public float getVignetteStart() { 42 | return vignetteStart; 43 | } 44 | 45 | public void setVignetteStart(final float vignetteStart) { 46 | this.vignetteStart = vignetteStart; 47 | } 48 | 49 | public float getVignetteEnd() { 50 | return vignetteEnd; 51 | } 52 | 53 | public void setVignetteEnd(final float vignetteEnd) { 54 | this.vignetteEnd = vignetteEnd; 55 | } 56 | 57 | ////////////////////////////////////////////////////////////////////////// 58 | 59 | @Override 60 | public void onDraw() { 61 | GLES20.glUniform2f(getHandle("vignetteCenter"), vignetteCenterX, vignetteCenterY); 62 | GLES20.glUniform1f(getHandle("vignetteStart"), vignetteStart); 63 | GLES20.glUniform1f(getHandle("vignetteEnd"), vignetteEnd); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/GlWatermarkComposeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | 6 | /** 7 | * Created by sudamasayuki2 on 2018/01/27. 8 | */ 9 | 10 | public class GlWatermarkComposeFilter extends GlOverlayComposeFilter { 11 | 12 | private Bitmap bitmap; 13 | private Position position = Position.LEFT_TOP; 14 | 15 | public GlWatermarkComposeFilter(Bitmap bitmap) { 16 | this.bitmap = bitmap; 17 | } 18 | 19 | 20 | public GlWatermarkComposeFilter(Bitmap bitmap, Position position) { 21 | this.bitmap = bitmap; 22 | this.position = position; 23 | } 24 | 25 | @Override 26 | protected void drawCanvas(Canvas canvas) { 27 | if (bitmap != null && !bitmap.isRecycled()) { 28 | switch (position) { 29 | case LEFT_TOP: 30 | canvas.drawBitmap(bitmap, 0, 0, null); 31 | break; 32 | case LEFT_BOTTOM: 33 | canvas.drawBitmap(bitmap, 0, canvas.getHeight() - bitmap.getHeight(), null); 34 | break; 35 | case RIGHT_TOP: 36 | canvas.drawBitmap(bitmap, canvas.getWidth() - bitmap.getWidth(), 0, null); 37 | break; 38 | case RIGHT_BOTTOM: 39 | canvas.drawBitmap(bitmap, canvas.getWidth() - bitmap.getWidth(), canvas.getHeight() - bitmap.getHeight(), null); 40 | break; 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public void release() { 47 | if (bitmap != null && !bitmap.isRecycled()) { 48 | bitmap.recycle(); 49 | } 50 | } 51 | 52 | public enum Position { 53 | LEFT_TOP, 54 | LEFT_BOTTOM, 55 | RIGHT_TOP, 56 | RIGHT_BOTTOM 57 | } 58 | } -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/filter/IResolutionFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.filter; 2 | 3 | import com.video.process.model.VideoSize; 4 | 5 | /** 6 | * Created by sudamasayuki on 2018/01/07. 7 | */ 8 | 9 | public interface IResolutionFilter { 10 | void setResolution(VideoSize resolution); 11 | } 12 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/compose/video/MediaCodecBufferCompatWrapper.java: -------------------------------------------------------------------------------- 1 | package com.video.process.compose.video; 2 | 3 | 4 | import android.media.MediaCodec; 5 | import android.os.Build; 6 | 7 | import java.nio.ByteBuffer; 8 | 9 | // Refer: https://github.com/ypresto/android-transcoder/blob/master/lib/src/main/java/net/ypresto/androidtranscoder/compat/MediaCodecBufferCompatWrapper.java 10 | 11 | /** 12 | * A Wrapper to MediaCodec that facilitates the use of API-dependent get{Input/Output}Buffer methods, 13 | * in order to prevent: http://stackoverflow.com/q/30646885 14 | */ 15 | 16 | public class MediaCodecBufferCompatWrapper { 17 | private final MediaCodec mediaCodec; 18 | private final ByteBuffer[] inputBuffers; 19 | private final ByteBuffer[] putputBuffers; 20 | 21 | public MediaCodecBufferCompatWrapper(MediaCodec mediaCodec) { 22 | this.mediaCodec = mediaCodec; 23 | 24 | if (Build.VERSION.SDK_INT < 21) { 25 | inputBuffers = mediaCodec.getInputBuffers(); 26 | putputBuffers = mediaCodec.getOutputBuffers(); 27 | } else { 28 | inputBuffers = putputBuffers = null; 29 | } 30 | } 31 | 32 | public ByteBuffer getInputBuffer(final int index) { 33 | if (Build.VERSION.SDK_INT >= 21) { 34 | return mediaCodec.getInputBuffer(index); 35 | } 36 | return inputBuffers[index]; 37 | } 38 | 39 | public ByteBuffer getOutputBuffer(final int index) { 40 | if (Build.VERSION.SDK_INT >= 21) { 41 | return mediaCodec.getOutputBuffer(index); 42 | } 43 | return putputBuffers[index]; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/exception/VideoProcessException.java: -------------------------------------------------------------------------------- 1 | package com.video.process.exception; 2 | 3 | public class VideoProcessException { 4 | 5 | public static final int ERR_INPUT_OR_OUTPUT_PATH = 100; 6 | public static final String ERR_STR_INPUT_OR_OUTPUT_PATH = "Input path or output path is null"; 7 | 8 | public static final int ERR_EXTRACTOR_SET_DATASOURCE = 101; 9 | public static final String ERR_STR_EXTRACTOR_SET_DATASOURCE = "MediaExtractor setDataSource failed"; 10 | 11 | public static final int ERR_INPUT_VIDEO_NO_DURATION = 102; 12 | public static final String ERR_STR_INPUT_VIDEO_NO_DURATION = "Input video has no duration"; 13 | 14 | public static final int ERR_NO_VIDEO_TRACK = 103; 15 | public static final String ERR_STR_NO_VIDEO_TRACK = "Input video has no vide track"; 16 | 17 | public static final int ERR_NO_AUDIO_TRACK = 104; 18 | public static final String ERR_STR_NO_AUDIO_TRACK = "Input video has no audio track"; 19 | 20 | public static final int ERR_MEDIAMUXER_CREATE_FAILED = 105; 21 | public static final String ERR_STR_MEDIAMUXER_CREATE_FAILED = "Create MediaMuxer failed"; 22 | 23 | public static final int ERR_INPUT_VIDEO_NO_KEYFRAME = 106; 24 | public static final String ERR_STR_INPUT_VIDEO_NO_KEYFRAME = "Input video has no key frame"; 25 | 26 | 27 | private String mErrStr; 28 | private int mErrorCode; 29 | 30 | public VideoProcessException(String errStr, int error) { 31 | mErrStr = errStr; 32 | mErrorCode = error; 33 | } 34 | 35 | public int getErrorCode() { return mErrorCode; } 36 | 37 | public String getExceptionStr() { return mErrStr; } 38 | 39 | public String toString() { 40 | return "VideoProcessException[error="+mErrorCode+", Exception="+mErrStr+"]"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/listener/IVideoProcessorListener.java: -------------------------------------------------------------------------------- 1 | package com.video.process.listener; 2 | 3 | import com.video.process.exception.VideoProcessException; 4 | 5 | public interface IVideoProcessorListener { 6 | 7 | void onVideoProcessorProgress(float progress); 8 | 9 | void onVideoProcessorFailed(VideoProcessException e); 10 | } 11 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/listener/IVideoReverseListener.java: -------------------------------------------------------------------------------- 1 | package com.video.process.listener; 2 | 3 | import com.video.process.exception.VideoProcessException; 4 | 5 | public interface IVideoReverseListener { 6 | 7 | void onVideoReverseProgress(float progress); 8 | void onVideoReverseFailed(VideoProcessException e); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/CustomFillMode.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | /** 7 | * Created by sudamasayuki2 on 2018/01/08. 8 | */ 9 | 10 | public class CustomFillMode implements Parcelable { 11 | private final float scale; 12 | private final float rotate; 13 | private final float translateX; 14 | private final float translateY; 15 | private final float videoWidth; 16 | private final float videoHeight; 17 | 18 | public CustomFillMode(float scale, float rotate, float translateX, float translateY, float videoWidth, float videoHeight) { 19 | this.scale = scale; 20 | this.rotate = rotate; 21 | this.translateX = translateX; 22 | this.translateY = translateY; 23 | this.videoWidth = videoWidth; 24 | this.videoHeight = videoHeight; 25 | } 26 | 27 | public float getScale() { 28 | return scale; 29 | } 30 | 31 | public float getRotate() { 32 | return rotate; 33 | } 34 | 35 | public float getTranslateX() { 36 | return translateX; 37 | } 38 | 39 | public float getTranslateY() { 40 | return translateY; 41 | } 42 | 43 | public float getVideoWidth() { 44 | return videoWidth; 45 | } 46 | 47 | public float getVideoHeight() { 48 | return videoHeight; 49 | } 50 | 51 | @Override 52 | public int describeContents() { 53 | return 0; 54 | } 55 | 56 | @Override 57 | public void writeToParcel(Parcel dest, int flags) { 58 | dest.writeFloat(this.scale); 59 | dest.writeFloat(this.rotate); 60 | dest.writeFloat(this.translateX); 61 | dest.writeFloat(this.translateY); 62 | dest.writeFloat(this.videoWidth); 63 | dest.writeFloat(this.videoHeight); 64 | } 65 | 66 | protected CustomFillMode(Parcel in) { 67 | this.scale = in.readFloat(); 68 | this.rotate = in.readFloat(); 69 | this.translateX = in.readFloat(); 70 | this.translateY = in.readFloat(); 71 | this.videoWidth = in.readFloat(); 72 | this.videoHeight = in.readFloat(); 73 | } 74 | 75 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 76 | @Override 77 | public CustomFillMode createFromParcel(Parcel source) { 78 | return new CustomFillMode(source); 79 | } 80 | 81 | @Override 82 | public CustomFillMode[] newArray(int size) { 83 | return new CustomFillMode[size]; 84 | } 85 | }; 86 | } 87 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/FillMode.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | /** 4 | * Created by sudamasayuki on 2018/01/01. 5 | */ 6 | 7 | public enum FillMode { 8 | PRESERVE_ASPECT_FIT, 9 | PRESERVE_ASPECT_CROP, 10 | CUSTOM; 11 | 12 | public static float[] getScaleAspectFit(int angle, int widthIn, int heightIn, int widthOut, int heightOut) { 13 | final float[] scale = {1, 1}; 14 | scale[0] = scale[1] = 1; 15 | if (angle == 90 || angle == 270) { 16 | int cx = widthIn; 17 | widthIn = heightIn; 18 | heightIn = cx; 19 | } 20 | 21 | float aspectRatioIn = (float) widthIn / (float) heightIn; 22 | float heightOutCalculated = (float) widthOut / aspectRatioIn; 23 | 24 | if (heightOutCalculated < heightOut) { 25 | scale[1] = heightOutCalculated / heightOut; 26 | } else { 27 | scale[0] = heightOut * aspectRatioIn / widthOut; 28 | } 29 | 30 | return scale; 31 | } 32 | 33 | public static float[] getScaleAspectCrop(int angle, int widthIn, int heightIn, int widthOut, int heightOut) { 34 | final float[] scale = {1, 1}; 35 | scale[0] = scale[1] = 1; 36 | if (angle == 90 || angle == 270) { 37 | int cx = widthIn; 38 | widthIn = heightIn; 39 | heightIn = cx; 40 | } 41 | 42 | float aspectRatioIn = (float) widthIn / (float) heightIn; 43 | float aspectRatioOut = (float) widthOut / (float) heightOut; 44 | 45 | if (aspectRatioIn > aspectRatioOut) { 46 | float widthOutCalculated = (float) heightOut * aspectRatioIn; 47 | scale[0] = widthOutCalculated / widthOut; 48 | } else { 49 | float heightOutCalculated = (float) widthOut / aspectRatioIn; 50 | scale[1] = heightOutCalculated / heightOut; 51 | } 52 | 53 | return scale; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/ProcessParams.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.video.process.preview.filter.GlFilterList; 6 | import com.video.process.preview.filter.GlFilter; 7 | 8 | public class ProcessParams { 9 | public String mInputVideoPath; //输入的源文件路径 10 | public String mInputAudioPath; //输入的音频文件的路径 11 | public String mOutputVideoPath; //生成文件的路径 12 | public VideoSize mOutputVideoSize; //生成视频文件大小 13 | public VideoSize mInputVideoSize; //源视频文件大小 14 | public VideoRange mVideoRange; //裁减的文件时间范围 15 | public int mBitRate; //视频的码率 16 | public int mFrameRate; //视频的帧率 17 | public boolean mIsMute; //是否静音 18 | public boolean mFlipVertical; //垂直翻转 19 | public boolean mFlipHorizontal; //水平翻转 20 | public int mRotateDegree; //旋转角度 21 | public int mTimeScale; //裁减的视频间隔 22 | public FillMode mFillMode; 23 | public CustomFillMode mCustomFillMode; 24 | public GlFilter mFilter; 25 | public GlFilterList mFilterList; 26 | 27 | public ProcessParams(@NonNull String inputVideoPath, @NonNull String outputVideoPath) { 28 | mInputVideoPath = inputVideoPath; 29 | mOutputVideoPath = outputVideoPath; 30 | } 31 | 32 | public void setInputAudioPath(@NonNull String inputAudioPath) { 33 | mInputAudioPath = inputAudioPath; 34 | } 35 | 36 | public void setOutputVideoSize(VideoSize size) { 37 | mOutputVideoSize = size; 38 | } 39 | 40 | public void setInputVideoSize(VideoSize size) { mInputVideoSize = size; } 41 | 42 | public void setVideoRange(VideoRange range) { 43 | mVideoRange = range; 44 | } 45 | 46 | public void setBitRate(int bitRate) { 47 | mBitRate = bitRate; 48 | } 49 | 50 | public void setFrameRate(int frameRate) { 51 | mFrameRate = frameRate; 52 | } 53 | 54 | public void setIsMute(boolean mute) { 55 | mIsMute = mute; 56 | } 57 | 58 | public void setFlipVertical(boolean flipVertical) { 59 | mFlipVertical = flipVertical; 60 | } 61 | 62 | public void setFlipHorizontal(boolean flipHorizontal) { 63 | mFlipHorizontal = flipHorizontal; 64 | } 65 | 66 | public void setRotateDegree(int degree) { 67 | mRotateDegree = degree; 68 | } 69 | 70 | public void setTimeScale(int scale) { 71 | mTimeScale = scale; 72 | } 73 | 74 | public void setFillMode(FillMode mode) { 75 | mFillMode = mode; 76 | } 77 | 78 | public void setCustomFillMode(CustomFillMode mode) { 79 | mCustomFillMode = mode; 80 | mFillMode = FillMode.CUSTOM; 81 | } 82 | 83 | public void setFilter(GlFilter filter) { 84 | mFilter = filter; 85 | } 86 | 87 | public void setFilterList(GlFilterList filterList) { 88 | mFilterList = filterList; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/Rotation.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/11/15. 5 | */ 6 | 7 | public enum Rotation { 8 | NORMAL(0), 9 | ROTATION_90(90), 10 | ROTATION_180(180), 11 | ROTATION_270(270); 12 | 13 | private final int rotation; 14 | 15 | Rotation(int rotation) { 16 | this.rotation = rotation; 17 | } 18 | 19 | public int getRotation() { 20 | return rotation; 21 | } 22 | 23 | public static Rotation fromInt(int rotate) { 24 | Rotation[] values = Rotation.values(); 25 | for (Rotation rotation : values) { 26 | if (rotate == rotation.getRotation()) return rotation; 27 | } 28 | return NORMAL; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/TrackType.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | public class TrackType { 4 | 5 | public static final int VIDEO = 1; 6 | public static final int AUDIO = 2; 7 | public static final int SUBTITLE = 3; 8 | } 9 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/VideoRange.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | public class VideoRange { 4 | 5 | public long mStart; 6 | public long mEnd; 7 | 8 | public VideoRange(long start, long end) { 9 | mStart = start; 10 | mEnd = end; 11 | } 12 | 13 | @Override 14 | public boolean equals(Object o) { 15 | if (this == o) return true; 16 | if (o == null || getClass() != o.getClass()) return false; 17 | VideoRange that = (VideoRange) o; 18 | return mStart == that.mStart && 19 | mEnd == that.mEnd; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/model/VideoSize.java: -------------------------------------------------------------------------------- 1 | package com.video.process.model; 2 | 3 | public class VideoSize { 4 | public int mWidth; 5 | public int mHeight; 6 | 7 | public VideoSize(int width, int height) { 8 | mWidth = width; 9 | mHeight = height; 10 | } 11 | 12 | @Override 13 | public boolean equals(Object o) { 14 | if (this == o) return true; 15 | if (o == null || getClass() != o.getClass()) return false; 16 | VideoSize videoSize = (VideoSize) o; 17 | return mWidth == videoSize.mWidth && 18 | mHeight == videoSize.mHeight; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/EFrameBufferObjectRenderer.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview; 2 | 3 | import android.opengl.GLES20; 4 | import android.opengl.GLSurfaceView; 5 | 6 | import com.video.process.preview.filter.GlFilter; 7 | 8 | import java.util.LinkedList; 9 | import java.util.Queue; 10 | 11 | import javax.microedition.khronos.egl.EGLConfig; 12 | import javax.microedition.khronos.opengles.GL10; 13 | 14 | import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; 15 | import static android.opengl.GLES20.GL_DEPTH_BUFFER_BIT; 16 | import static android.opengl.GLES20.GL_FRAMEBUFFER; 17 | 18 | /** 19 | * Created by sudamasayuki on 2017/05/16. 20 | */ 21 | 22 | abstract class EFrameBufferObjectRenderer implements GLSurfaceView.Renderer { 23 | 24 | private EFramebufferObject framebufferObject; 25 | private GlFilter normalShader; 26 | 27 | private final Queue runOnDraw; 28 | 29 | private boolean useFBO = true; 30 | 31 | 32 | EFrameBufferObjectRenderer() { 33 | runOnDraw = new LinkedList(); 34 | } 35 | 36 | 37 | @Override 38 | public final void onSurfaceCreated(final GL10 gl, final EGLConfig config) { 39 | framebufferObject = new EFramebufferObject(); 40 | normalShader = new GlFilter(); 41 | normalShader.setup(); 42 | onSurfaceCreated(config); 43 | } 44 | 45 | @Override 46 | public final void onSurfaceChanged(final GL10 gl, final int width, final int height) { 47 | framebufferObject.setup(width, height); 48 | normalShader.setFrameSize(width, height); 49 | onSurfaceChanged(width, height); 50 | } 51 | 52 | @Override 53 | public final void onDrawFrame(final GL10 gl) { 54 | synchronized (runOnDraw) { 55 | while (!runOnDraw.isEmpty()) { 56 | runOnDraw.poll().run(); 57 | } 58 | } 59 | if (useFBO) { 60 | framebufferObject.enable(); 61 | } 62 | GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); 63 | 64 | onDrawFrame(framebufferObject); 65 | 66 | if (useFBO) { 67 | // 在最外层, 最终把输出从屏幕输出 68 | GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0); 69 | GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); 70 | 71 | GLES20.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 72 | normalShader.draw(framebufferObject.getTexName(), null, null); 73 | } 74 | 75 | 76 | } 77 | 78 | @Override 79 | protected void finalize() throws Throwable { 80 | 81 | } 82 | 83 | public abstract void onSurfaceCreated(EGLConfig config); 84 | 85 | public abstract void onSurfaceChanged(int width, int height); 86 | 87 | public abstract void onDrawFrame(EFramebufferObject fbo); 88 | } 89 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/ESurfaceTexture.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview; 2 | 3 | import android.graphics.SurfaceTexture; 4 | 5 | import com.video.process.preview.filter.GlPreviewFilter; 6 | 7 | /** 8 | * Created by sudamasayuki on 2017/05/16. 9 | */ 10 | 11 | class ESurfaceTexture implements SurfaceTexture.OnFrameAvailableListener { 12 | 13 | private SurfaceTexture surfaceTexture; 14 | private SurfaceTexture.OnFrameAvailableListener onFrameAvailableListener; 15 | 16 | ESurfaceTexture(final int texName) { 17 | surfaceTexture = new SurfaceTexture(texName); 18 | surfaceTexture.setOnFrameAvailableListener(this); 19 | } 20 | 21 | void setOnFrameAvailableListener(final SurfaceTexture.OnFrameAvailableListener l) { 22 | onFrameAvailableListener = l; 23 | } 24 | 25 | 26 | int getTextureTarget() { 27 | return GlPreviewFilter.GL_TEXTURE_EXTERNAL_OES; 28 | } 29 | 30 | void updateTexImage() { 31 | surfaceTexture.updateTexImage(); 32 | } 33 | 34 | void getTransformMatrix(final float[] mtx) { 35 | surfaceTexture.getTransformMatrix(mtx); 36 | } 37 | 38 | SurfaceTexture getSurfaceTexture() { 39 | return surfaceTexture; 40 | } 41 | 42 | public void onFrameAvailable(final SurfaceTexture surfaceTexture) { 43 | if (onFrameAvailableListener != null) { 44 | onFrameAvailableListener.onFrameAvailable(this.surfaceTexture); 45 | } 46 | } 47 | 48 | public void release() { 49 | surfaceTexture.release(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/GlPlayerView.kt: -------------------------------------------------------------------------------- 1 | package com.video.process.preview 2 | 3 | import android.content.Context 4 | import android.graphics.SurfaceTexture 5 | import android.os.Handler 6 | import android.util.AttributeSet 7 | 8 | import com.video.process.surface.MPlayerView 9 | import com.video.player.player.mp.TextureSurfaceRenderer2 10 | 11 | class GlPlayerView : MPlayerView { 12 | 13 | var listener: ((Long) -> Unit)? = null 14 | var uiHandler: Handler = Handler() 15 | 16 | constructor(context: Context) : super(context) {} 17 | 18 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} 19 | 20 | override fun getVideoRender(surface: SurfaceTexture, width: Int, height: Int): TextureSurfaceRenderer2 { 21 | val renderer = VideoTextureSurfaceRenderer2(context) 22 | renderer.setUpSurfaceTexture(surface, width, height) 23 | return renderer 24 | } 25 | 26 | fun setProgressListener(function: (Long) -> Unit) { 27 | listener = function 28 | 29 | uiHandler.post { checkPlayProgress() } 30 | } 31 | 32 | private fun checkPlayProgress() { 33 | if (!notDestroyed) { 34 | return 35 | } 36 | if (listener != null && mMediaPlayer != null && mMediaPlayer.isPlaying) { 37 | currentPostion = mMediaPlayer.currentPosition.toLong() 38 | listener?.invoke(currentPostion) 39 | uiHandler?.postDelayed({ checkPlayProgress() }, 100) 40 | } else { 41 | uiHandler?.postDelayed({ checkPlayProgress() }, 200) 42 | } 43 | 44 | } 45 | 46 | override fun release() { 47 | super.release() 48 | uiHandler.removeCallbacksAndMessages(null) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/PlayerScaleType.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/16. 5 | */ 6 | 7 | public enum PlayerScaleType { 8 | RESIZE_FIT_WIDTH, // 9 | RESIZE_FIT_HEIGHT, // 10 | RESIZE_NONE, // The specified aspect ratio is ignored. 11 | ; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/TextureSurfaceFBORenderer.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.preview.filter.GlFilter; 6 | import com.video.player.player.mp.TextureSurfaceRenderer; 7 | 8 | import javax.microedition.khronos.egl.EGLConfig; 9 | 10 | import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; 11 | import static android.opengl.GLES20.GL_DEPTH_BUFFER_BIT; 12 | import static android.opengl.GLES20.GL_FRAMEBUFFER; 13 | 14 | public abstract class TextureSurfaceFBORenderer extends TextureSurfaceRenderer { 15 | 16 | private EFramebufferObject framebufferObject; 17 | private GlFilter normalShader; 18 | 19 | public TextureSurfaceFBORenderer() { 20 | super(); 21 | } 22 | 23 | @Override 24 | protected void initGLComponents() { 25 | framebufferObject = new EFramebufferObject(); 26 | normalShader = new GlFilter(); 27 | normalShader.setup(); 28 | } 29 | 30 | @Override 31 | public void onSurfaceChanged(int width, int height) { 32 | this.mWidth = width; 33 | this.mHeight = height; 34 | framebufferObject.setup(width, height); 35 | normalShader.setFrameSize(width, height); 36 | } 37 | 38 | @Override 39 | protected boolean onDrawFrame() { 40 | framebufferObject.enable(); 41 | GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); 42 | 43 | onDrawFrame(framebufferObject); 44 | 45 | 46 | // 在最外层, 最终把输出从屏幕输出 47 | GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0); 48 | GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); 49 | 50 | GLES20.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 51 | normalShader.draw(framebufferObject.getTexName(), null, null); 52 | return true; 53 | } 54 | 55 | 56 | 57 | @Override 58 | protected void deinitGLComponents() { 59 | 60 | } 61 | 62 | // @Override 63 | // public SurfaceTexture getVideoTexture() { 64 | // return null; 65 | // } 66 | 67 | public abstract void onSurfaceCreated(EGLConfig config); 68 | 69 | public abstract void onDrawFrame(EFramebufferObject fbo); 70 | } 71 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/contextfactory/EContextFactory.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.contextfactory; 2 | 3 | import android.opengl.GLSurfaceView; 4 | import android.util.Log; 5 | 6 | import javax.microedition.khronos.egl.EGL10; 7 | import javax.microedition.khronos.egl.EGLConfig; 8 | import javax.microedition.khronos.egl.EGLContext; 9 | import javax.microedition.khronos.egl.EGLDisplay; 10 | 11 | import static javax.microedition.khronos.egl.EGL10.EGL_NONE; 12 | import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT; 13 | 14 | /** 15 | * Created by sudamasayuki on 2017/05/16. 16 | */ 17 | 18 | public class EContextFactory implements GLSurfaceView.EGLContextFactory { 19 | 20 | private static final String TAG = "EContextFactory"; 21 | 22 | private final int EGL_CLIENT_VERSION = 2; 23 | 24 | private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 25 | 26 | @Override 27 | public EGLContext createContext(final EGL10 egl, final EGLDisplay display, final EGLConfig config) { 28 | final int[] attrib_list; 29 | attrib_list = new int[]{EGL_CONTEXT_CLIENT_VERSION, EGL_CLIENT_VERSION, EGL_NONE}; 30 | return egl.eglCreateContext(display, config, EGL_NO_CONTEXT, attrib_list); 31 | } 32 | 33 | @Override 34 | public void destroyContext(final EGL10 egl, final EGLDisplay display, final EGLContext context) { 35 | if (!egl.eglDestroyContext(display, context)) { 36 | Log.e(TAG, "display:" + display + " context: " + context); 37 | throw new RuntimeException("eglDestroyContex" + egl.eglGetError()); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GLImageAmaroFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import com.video.process.preview.filter.GlFilter; 4 | 5 | public class GLImageAmaroFilter extends GlFilter { 6 | private static final String FRAGMENT_SHADER = "" + 7 | "precision mediump float;\n" + 8 | " \n" + 9 | " varying mediump vec2 textureCoordinate;\n" + 10 | " \n" + 11 | " uniform sampler2D inputTexture;\n" + 12 | " uniform sampler2D blowoutTexture; //blowout;\n" + 13 | " uniform sampler2D overlayTexture; //overlay;\n" + 14 | " uniform sampler2D mapTexture; //map\n" + 15 | " \n" + 16 | " uniform float strength;\n" + 17 | "\n" + 18 | " void main()\n" + 19 | " {\n" + 20 | " vec4 originColor = texture2D(inputTexture, textureCoordinate);\n" + 21 | " vec4 texel = texture2D(inputTexture, textureCoordinate);\n" + 22 | " vec3 bbTexel = texture2D(blowoutTexture, textureCoordinate).rgb;\n" + 23 | " \n" + 24 | " texel.r = texture2D(overlayTexture, vec2(bbTexel.r, texel.r)).r;\n" + 25 | " texel.g = texture2D(overlayTexture, vec2(bbTexel.g, texel.g)).g;\n" + 26 | " texel.b = texture2D(overlayTexture, vec2(bbTexel.b, texel.b)).b;\n" + 27 | " \n" + 28 | " vec4 mapped;\n" + 29 | " mapped.r = texture2D(mapTexture, vec2(texel.r, 0.16666)).r;\n" + 30 | " mapped.g = texture2D(mapTexture, vec2(texel.g, 0.5)).g;\n" + 31 | " mapped.b = texture2D(mapTexture, vec2(texel.b, 0.83333)).b;\n" + 32 | " mapped.a = 1.0;\n" + 33 | " \n" + 34 | " mapped.rgb = mix(originColor.rgb, mapped.rgb, strength);\n" + 35 | "\n" + 36 | " gl_FragColor = mapped;\n" + 37 | " }"; 38 | } 39 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GLImageBeautyHighPassFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import com.video.process.preview.filter.GlFilter; 6 | 7 | public class GLImageBeautyHighPassFilter extends GlFilter { 8 | protected static final String VERTEX_SHADER = "" + 9 | "uniform mat4 uMVPMatrix; \n" + 10 | "attribute vec4 aPosition; \n" + 11 | "attribute vec4 aTextureCoord; \n" + 12 | "varying vec2 textureCoordinate; \n" + 13 | "void main() { \n" + 14 | " gl_Position = uMVPMatrix * aPosition; \n" + 15 | " textureCoordinate = aTextureCoord.xy; \n" + 16 | "} \n"; 17 | private static final String FRAGMENT_SHADER = "" + 18 | "precision mediump float;\n" + 19 | "varying vec2 textureCoordinate;\n" + 20 | "uniform sampler2D inputTexture; // 输入原图\n" + 21 | "uniform sampler2D blurTexture; // 高斯模糊图片\n" + 22 | "const float intensity = 24.0; // 强光程度\n" + 23 | "void main() {\n" + 24 | " lowp vec4 sourceColor = texture2D(inputTexture, textureCoordinate);\n" + 25 | " lowp vec4 blurColor = texture2D(blurTexture, textureCoordinate);\n" + 26 | " // 高通滤波之后的颜色值\n" + 27 | " highp vec4 highPassColor = sourceColor - blurColor;\n" + 28 | " // 对应混合模式中的强光模式(color = 2.0 * color1 * color2),对于高反差的颜色来说,color1 和color2 是同一个\n" + 29 | " highPassColor.r = clamp(2.0 * highPassColor.r * highPassColor.r * intensity, 0.0, 1.0);\n" + 30 | " highPassColor.g = clamp(2.0 * highPassColor.g * highPassColor.g * intensity, 0.0, 1.0);\n" + 31 | " highPassColor.b = clamp(2.0 * highPassColor.b * highPassColor.b * intensity, 0.0, 1.0);\n" + 32 | " // 输出的是把痘印等过滤掉\n" + 33 | " gl_FragColor = vec4(highPassColor.rgb, 1.0);\n" + 34 | "}"; 35 | 36 | private int mBlurTextureHandle; 37 | private int mBlurTexture; 38 | 39 | public GLImageBeautyHighPassFilter() { 40 | this(VERTEX_SHADER, FRAGMENT_SHADER); 41 | } 42 | 43 | public GLImageBeautyHighPassFilter(String vertexShader, String fragmentShader) { 44 | super(vertexShader, fragmentShader); 45 | } 46 | 47 | public void setBlurTexture(int texture) { 48 | mBlurTexture = texture; 49 | } 50 | 51 | @Override 52 | protected void onDraw() { 53 | super.onDraw(); 54 | GLES30.glActiveTexture(GLES30.GL_TEXTURE1); 55 | GLES30.glBindTexture( GLES30.GL_TEXTURE_2D, mBlurTexture); 56 | GLES30.glUniform1i(getHandle("blurTexture"), 1); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/Gl4SplitFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | 5 | import com.video.process.R; 6 | import com.video.process.preview.filter.FilterType; 7 | import com.video.process.preview.filter.GlFilter; 8 | 9 | public class Gl4SplitFilter extends GlFilter { 10 | 11 | 12 | public Gl4SplitFilter(Context context) { 13 | super(context, R.raw.def_vertext, R.raw.fragment_split4); 14 | } 15 | 16 | @Override 17 | public FilterType getFilterType() { 18 | return FilterType.SPX_4SPLIT; 19 | } 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlBeautyBlurFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | import com.video.process.preview.filter.GlFilter; 6 | 7 | public class GlBeautyBlurFilter extends GlFilter { 8 | private static final String FRAGMENT_SHADER = "" ; 9 | private float opacity = 0.5f; 10 | private int width = 1080; 11 | private int height = 1920; 12 | // 高斯模糊处理的图像缩放倍数 13 | private float mBlurScale = 0.5f; 14 | 15 | public GlBeautyBlurFilter() { 16 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 17 | } 18 | 19 | public float getOpacity() { 20 | return opacity; 21 | } 22 | 23 | public void setOpacity(final float opacity) { 24 | this.opacity = opacity; 25 | } 26 | 27 | @Override 28 | public void setFrameSize(int width, int height) { 29 | super.setFrameSize(width, height); 30 | this.width = width; 31 | this.height = height; 32 | } 33 | 34 | @Override 35 | public void onDraw() { 36 | GLES20.glUniform1f(getHandle("opacity"), opacity); 37 | GLES20.glUniform1i(getHandle("width"), width); 38 | GLES20.glUniform1i(getHandle("height"), height); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlBeautyGroupFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import com.video.process.preview.filter.GlFilterGroup; 4 | 5 | public class GlBeautyGroupFilter extends GlFilterGroup { 6 | 7 | public GlBeautyGroupFilter(){ 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlFlashFliter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | import android.opengl.GLES30; 6 | 7 | import com.video.process.R; 8 | import com.video.process.preview.filter.FilterType; 9 | import com.video.process.preview.filter.GlFilter; 10 | 11 | public class GlFlashFliter extends GlFilter { 12 | 13 | 14 | private int mExposeHandle; 15 | private int mFrames; 16 | 17 | private int mMaxFrames = 8; 18 | 19 | private int mHalfFrames = mMaxFrames / 2; 20 | 21 | public GlFlashFliter(Context context) { 22 | super(context, R.raw.def_vertext, R.raw.fragment_flash); 23 | } 24 | 25 | @Override 26 | public FilterType getFilterType() { 27 | return FilterType.SPX_FLASH; 28 | } 29 | 30 | @Override 31 | public void initProgramHandle() { 32 | super.initProgramHandle(); 33 | mExposeHandle = GLES30.glGetUniformLocation(mProgramHandle, "uAdditionalColor"); 34 | } 35 | 36 | @Override 37 | public void onDraw() { 38 | float progress; 39 | if (mFrames <= mHalfFrames) { 40 | progress = mFrames * 1.0f / mHalfFrames; 41 | } else { 42 | progress = 2.0f - mFrames * 1.0f / mHalfFrames; 43 | } 44 | mFrames++; 45 | if (mFrames > mMaxFrames) { 46 | mFrames = 0; 47 | } 48 | GLES20.glUniform1f(mExposeHandle, progress); 49 | 50 | 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlHuanJueFliter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES30; 5 | import android.util.Log; 6 | 7 | import com.video.process.R; 8 | import com.video.process.preview.filter.FilterType; 9 | import com.video.process.preview.filter.GlFilter; 10 | import com.video.player.util.GlUtil; 11 | 12 | import java.util.Map; 13 | 14 | public class GlHuanJueFliter extends GlFilter { 15 | private static final String TAG = "GlHuanJueFliter"; 16 | 17 | private int mLutTexture; 18 | private int uTexture1Handle; 19 | private int uTexture2Handle; 20 | private static final String DIR_NAME = "filters/"; 21 | private String pngResName = "lookup_vertigo"; 22 | 23 | public GlHuanJueFliter(Context context) { 24 | super(context, R.raw.def_vertext, R.raw.fragment_canying); 25 | } 26 | 27 | @Override 28 | public FilterType getFilterType() { 29 | return FilterType.SPX_LUCION; 30 | } 31 | 32 | @Override 33 | public void initProgramHandle() { 34 | super.initProgramHandle(); 35 | uTexture1Handle = GLES30.glGetUniformLocation(mProgramHandle, "uTexture1"); 36 | uTexture2Handle = GLES30.glGetUniformLocation(mProgramHandle, "uTexture2"); 37 | createTexture(); 38 | } 39 | 40 | /** 41 | * 创建纹理 42 | */ 43 | private void createTexture() { 44 | mLutTexture = GlUtil.createTextureFromAssets(mContext, 45 | DIR_NAME + pngResName + ".png"); 46 | } 47 | 48 | @Override 49 | public void onDraw(Map extraTextureIds) { 50 | GLES30.glActiveTexture(GLES30.GL_TEXTURE3); 51 | GLES30.glBindTexture(getTextureType(), mLutTexture); 52 | GLES30.glUniform1i(uTexture2Handle, 3); 53 | 54 | 55 | if (extraTextureIds.containsKey("last_frame_texture")) { 56 | Integer last_frame_texture = extraTextureIds.get("last_frame_texture"); 57 | Log.d(TAG, "onDraw: last_frame_texture:" + last_frame_texture); 58 | 59 | GLES30.glActiveTexture(GLES30.GL_TEXTURE4); 60 | GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, last_frame_texture); 61 | GLES30.glUniform1i(uTexture1Handle, 4); 62 | } 63 | 64 | 65 | } 66 | 67 | public boolean needLastFrame() { 68 | return true; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlItchFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | 5 | import com.video.process.R; 6 | import com.video.process.preview.filter.FilterType; 7 | import com.video.process.preview.filter.GlFilter; 8 | 9 | import static android.opengl.GLES20.glGetUniformLocation; 10 | import static android.opengl.GLES20.glUniform1f; 11 | import static android.opengl.GLES20.glUniform2fv; 12 | 13 | public class GlItchFilter extends GlFilter { 14 | 15 | private int mScanLineJitterLocation; 16 | private int mColorDriftLocation; 17 | private int mGlobalTimeLocation; 18 | 19 | private long mStartTime; 20 | 21 | private int mFrames = 0; 22 | 23 | /** 24 | * 动画总共8帧 25 | */ 26 | private int mMaxFrames = 8; 27 | 28 | private float[] mDriftSequence = new float[]{0f, 0.03f, 0.032f, 0.035f, 0.03f, 0.032f, 0.031f, 0.029f, 0.025f}; 29 | 30 | private float[] mJitterSequence = new float[]{0f, 0.03f, 0.01f, 0.02f, 0.05f, 0.055f, 0.03f, 0.02f, 0.025f}; 31 | 32 | private float[] mThreshHoldSequence = new float[]{1.0f, 0.965f, 0.9f, 0.9f, 0.9f, 0.6f, 0.8f, 0.5f, 0.5f}; 33 | 34 | 35 | public GlItchFilter(Context context) { 36 | super(context, R.raw.def_vertext, R.raw.fragment_itch); 37 | } 38 | 39 | @Override 40 | public FilterType getFilterType() { 41 | return FilterType.SPX_ITCH; 42 | } 43 | 44 | @Override 45 | public void initProgramHandle() { 46 | super.initProgramHandle(); 47 | mScanLineJitterLocation = glGetUniformLocation(mProgramHandle, "uScanLineJitter"); 48 | mColorDriftLocation = glGetUniformLocation(mProgramHandle, "uColorDrift"); 49 | mGlobalTimeLocation = glGetUniformLocation(mProgramHandle, "uGlobalTime"); 50 | } 51 | 52 | 53 | @Override 54 | public void onDraw() { 55 | long time = System.currentTimeMillis(); 56 | if (mStartTime == 0) { 57 | mStartTime = time; 58 | } 59 | glUniform1f(mGlobalTimeLocation, mFrames); 60 | mStartTime = time; 61 | 62 | float slDisplacement = mJitterSequence[mFrames]; 63 | float slThreshold = mThreshHoldSequence[mFrames]; 64 | float drift = mDriftSequence[mFrames]; 65 | mFrames++; 66 | if (mFrames > mMaxFrames) { 67 | mFrames = 0; 68 | } 69 | glUniform2fv(mScanLineJitterLocation, 1, new float[]{slDisplacement, slThreshold}, 0); 70 | glUniform1f(mColorDriftLocation, drift); 71 | 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlScaleFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | import android.opengl.GLES30; 6 | 7 | import com.video.process.R; 8 | import com.video.process.preview.filter.FilterType; 9 | import com.video.process.preview.filter.GlFilter; 10 | 11 | public class GlScaleFilter extends GlFilter { 12 | 13 | float mScale = 0f; 14 | float mOffset = 0f; 15 | private int mScaleHandle; 16 | private boolean plus = false; 17 | 18 | public GlScaleFilter(Context context) { 19 | super(context, R.raw.def_vertext, R.raw.fragment_scale); 20 | } 21 | 22 | @Override 23 | public FilterType getFilterType() { 24 | return FilterType.SPX_SCALE; 25 | } 26 | 27 | @Override 28 | public void initProgramHandle() { 29 | super.initProgramHandle(); 30 | mScaleHandle = GLES30.glGetUniformLocation(mProgramHandle, "scale"); 31 | } 32 | 33 | @Override 34 | public void onDraw() { 35 | mOffset += plus ? +0.06f : -0.06f; 36 | if (mOffset >= 1.0f) { 37 | plus = false; 38 | } else if (mOffset <= 0.0f) { 39 | plus = true; 40 | } 41 | mScale = 1.0f + 0.5f * getInterpolation(mOffset); 42 | GLES20.glUniform1f(mScaleHandle, mScale); 43 | 44 | 45 | } 46 | 47 | private float getInterpolation(float input) { 48 | return (float) (Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; 49 | } 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlShakeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | import android.opengl.GLES30; 6 | 7 | import com.video.process.R; 8 | import com.video.process.preview.filter.FilterType; 9 | import com.video.process.preview.filter.GlFilter; 10 | 11 | public class GlShakeFilter extends GlFilter { 12 | 13 | float mScale = 0f; 14 | float mOffset = 0f; 15 | private int mScaleHandle; 16 | private boolean plus = false; 17 | 18 | public GlShakeFilter(Context context) { 19 | super(context, R.raw.def_vertext, R.raw.fragment_shake); 20 | } 21 | 22 | @Override 23 | public FilterType getFilterType() { 24 | return FilterType.SPX_SHAKE; 25 | } 26 | 27 | @Override 28 | public void initProgramHandle() { 29 | super.initProgramHandle(); 30 | mScaleHandle = GLES30.glGetUniformLocation(mProgramHandle, "scale"); 31 | } 32 | 33 | @Override 34 | public void onDraw() { 35 | mScale = 1.0f + 0.3f * getInterpolation(mOffset); 36 | mOffset += 0.06f; 37 | if (mOffset > 1.0f) { 38 | mOffset = 0.0f; 39 | } 40 | GLES20.glUniform1f(mScaleHandle, mScale); 41 | 42 | } 43 | 44 | private float getInterpolation(float input) { 45 | return (float) (Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/custfilter/GlSoulOutFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.custfilter; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | import android.opengl.GLES30; 6 | 7 | import com.video.process.R; 8 | import com.video.process.preview.filter.FilterType; 9 | import com.video.process.preview.filter.GlFilter; 10 | 11 | public class GlSoulOutFilter extends GlFilter { 12 | 13 | float mScale = 0f; 14 | float mOffset = 0f; 15 | private int mScaleHandle; 16 | 17 | public GlSoulOutFilter(Context context) { 18 | super(context, R.raw.def_vertext, R.raw.fragment_soulout); 19 | } 20 | 21 | @Override 22 | public FilterType getFilterType() { 23 | return FilterType.SPX_SOULOUT; 24 | } 25 | 26 | @Override 27 | public void initProgramHandle() { 28 | super.initProgramHandle(); 29 | mScaleHandle = GLES30.glGetUniformLocation(mProgramHandle, "scale"); 30 | } 31 | 32 | @Override 33 | public void onDraw() { 34 | mScale = 1.0f + 0.5f * getInterpolation(mOffset); 35 | mOffset += 0.04f; 36 | if (mOffset > 1.0f) { 37 | mOffset = 0.0f; 38 | } 39 | GLES20.glUniform1f(mScaleHandle, mScale); 40 | 41 | } 42 | 43 | private float getInterpolation(float input) { 44 | return (float) (Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlBulgeDistortionFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/05/18. 7 | */ 8 | 9 | public class GlBulgeDistortionFilter extends GlFilter { 10 | 11 | private static final String FRAGMENT_SHADER = 12 | "precision mediump float;" + 13 | 14 | "varying highp vec2 vTextureCoord;" + 15 | "uniform lowp sampler2D sTexture;" + 16 | 17 | "uniform highp vec2 center;" + 18 | "uniform highp float radius;" + 19 | "uniform highp float scale;" + 20 | 21 | "void main() {" + 22 | "highp vec2 textureCoordinateToUse = vTextureCoord;" + 23 | "highp float dist = distance(center, vTextureCoord);" + 24 | "textureCoordinateToUse -= center;" + 25 | "if (dist < radius) {" + 26 | "highp float percent = 1.0 - ((radius - dist) / radius) * scale;" + 27 | "percent = percent * percent;" + 28 | "textureCoordinateToUse = textureCoordinateToUse * percent;" + 29 | "}" + 30 | "textureCoordinateToUse += center;" + 31 | 32 | "gl_FragColor = texture2D(sTexture, textureCoordinateToUse);" + 33 | "}"; 34 | 35 | private float centerX = 0.5f; 36 | private float centerY = 0.5f; 37 | private float radius = 0.25f; 38 | private float scale = 0.5f; 39 | 40 | public GlBulgeDistortionFilter() { 41 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 42 | } 43 | 44 | public float getCenterX() { 45 | return centerX; 46 | } 47 | 48 | public void setCenterX(final float centerX) { 49 | this.centerX = centerX; 50 | } 51 | 52 | public float getCenterY() { 53 | return centerY; 54 | } 55 | 56 | public void setCenterY(final float centerY) { 57 | this.centerY = centerY; 58 | } 59 | 60 | public float getRadius() { 61 | return radius; 62 | } 63 | 64 | public void setRadius(final float radius) { 65 | this.radius = radius; 66 | } 67 | 68 | public float getScale() { 69 | return scale; 70 | } 71 | 72 | public void setScale(final float scale) { 73 | this.scale = scale; 74 | } 75 | 76 | ////////////////////////////////////////////////////////////////////////// 77 | 78 | @Override 79 | public void onDraw() { 80 | GLES20.glUniform2f(getHandle("center"), centerX, centerY); 81 | GLES20.glUniform1f(getHandle("radius"), radius); 82 | GLES20.glUniform1f(getHandle("scale"), scale); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlCGAColorspaceFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/18. 5 | */ 6 | 7 | public class GlCGAColorspaceFilter extends GlFilter { 8 | 9 | private static final String FRAGMENT_SHADER = 10 | "precision mediump float;" + 11 | 12 | "varying vec2 vTextureCoord;" + 13 | "uniform lowp sampler2D sTexture;" + 14 | 15 | "void main() {" + 16 | "highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);" + 17 | 18 | "highp vec2 samplePos = vTextureCoord - mod(vTextureCoord, sampleDivisor);" + 19 | "highp vec4 color = texture2D(sTexture, samplePos);" + 20 | 21 | "mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);" + 22 | "mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);" + 23 | "mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);" + 24 | "mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);" + 25 | 26 | "mediump vec4 endColor;" + 27 | "highp float blackDistance = distance(color, colorBlack);" + 28 | "highp float whiteDistance = distance(color, colorWhite);" + 29 | "highp float magentaDistance = distance(color, colorMagenta);" + 30 | "highp float cyanDistance = distance(color, colorCyan);" + 31 | 32 | "mediump vec4 finalColor;" + 33 | 34 | "highp float colorDistance = min(magentaDistance, cyanDistance);" + 35 | "colorDistance = min(colorDistance, whiteDistance);" + 36 | "colorDistance = min(colorDistance, blackDistance);" + 37 | 38 | "if (colorDistance == blackDistance) {" + 39 | "finalColor = colorBlack;" + 40 | "} else if (colorDistance == whiteDistance) {" + 41 | "finalColor = colorWhite;" + 42 | "} else if (colorDistance == cyanDistance) {" + 43 | "finalColor = colorCyan;" + 44 | "} else {" + 45 | "finalColor = colorMagenta;" + 46 | "}" + 47 | 48 | "gl_FragColor = finalColor;" + 49 | "}"; 50 | 51 | 52 | public GlCGAColorspaceFilter() { 53 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlFilterConfig.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import com.video.process.preview.filter.FilterType; 4 | 5 | import java.io.Serializable; 6 | 7 | public class GlFilterConfig implements Serializable { 8 | public FilterType filterName; 9 | public long startTimeMs; 10 | public long endTimeMs; 11 | 12 | public GlFilterConfig(FilterType filterName, long startTimeMs, long endTimeMs) { 13 | this.filterName = filterName; 14 | this.startTimeMs = startTimeMs; 15 | this.endTimeMs = endTimeMs; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlFilterList.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.util.Log; 4 | 5 | import com.video.process.preview.EFramebufferObject; 6 | 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.LinkedList; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created by shaopx on 2018/11/05. 14 | * glfiter list , time aware 15 | * its name is like a list , But, one time one filter. different with GlFilterGroup. 16 | */ 17 | public class GlFilterList { 18 | 19 | private static final String TAG = "GlFilterList"; 20 | private final LinkedList glFilerPeriod = new LinkedList<>(); 21 | private boolean needLastFrame = false; 22 | 23 | public GlFilterList() { 24 | glFilerPeriod.add(0, new GlFilterPeriod(0, 600 * 1000, new GlFilter())); 25 | } 26 | 27 | public void putGlFilter(GlFilterPeriod period) { 28 | // period.filter.setup(); 29 | glFilerPeriod.add(0, period); 30 | } 31 | 32 | public GlFilter getGlFilter(long time) { 33 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 34 | if (glFilterPeriod.contains(time)) { 35 | return glFilterPeriod.filter; 36 | } 37 | } 38 | return null; 39 | } 40 | 41 | public void draw(int texName, EFramebufferObject fbo, long presentationTimeUs, Map extraTextureIds) { 42 | Log.d(TAG, "draw: presentationTimeUs:"+presentationTimeUs+", glFilerPeriod:"+glFilerPeriod); 43 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 44 | if (glFilterPeriod.contains(presentationTimeUs / (1000*1000))) { 45 | needLastFrame = glFilterPeriod.filter.needLastFrame(); 46 | Log.d(TAG, "draw: filter:"+glFilterPeriod.filter.getName()); 47 | glFilterPeriod.filter.draw(texName, fbo, extraTextureIds); 48 | return; 49 | } 50 | } 51 | } 52 | 53 | public void release() { 54 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 55 | glFilterPeriod.filter.release(); 56 | } 57 | } 58 | 59 | public void setFrameSize(int width, int height) { 60 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 61 | glFilterPeriod.filter.setFrameSize(width, height); 62 | } 63 | } 64 | 65 | public void setup() { 66 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 67 | glFilterPeriod.filter.setup(); 68 | } 69 | } 70 | 71 | public boolean needLastFrame() { 72 | return needLastFrame; 73 | } 74 | 75 | @NotNull 76 | public GlFilterList copy() { 77 | GlFilterList filterList = new GlFilterList(); 78 | for (GlFilterPeriod glFilterPeriod : glFilerPeriod) { 79 | filterList.putGlFilter(glFilterPeriod.copy()); 80 | } 81 | return filterList; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlFilterPeriod.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import java.io.Serializable; 4 | 5 | public class GlFilterPeriod implements Serializable { 6 | public long startTimeMs; 7 | public long endTimeMs; 8 | public GlFilter filter; 9 | 10 | public GlFilterPeriod(long startTimeMs, long endTimeMs, GlFilter filter) { 11 | this.startTimeMs = startTimeMs; 12 | this.endTimeMs = endTimeMs; 13 | this.filter = filter; 14 | } 15 | 16 | public boolean contains(long time) { 17 | return time >= startTimeMs && time <= endTimeMs; 18 | } 19 | 20 | public boolean touched(GlFilterPeriod period) { 21 | return false; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "[" + startTimeMs + "," + endTimeMs + "]" + filter.getName() + ";"; 27 | } 28 | 29 | public GlFilterPeriod copy() { 30 | GlFilterPeriod period = new GlFilterPeriod(startTimeMs, endTimeMs, filter); 31 | return period; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlGrayScaleFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/18. 5 | */ 6 | 7 | public class GlGrayScaleFilter extends GlFilter { 8 | 9 | private static final String FRAGMENT_SHADER = 10 | "precision mediump float;" + 11 | "varying vec2 vTextureCoord;" + 12 | "uniform lowp sampler2D sTexture;" + 13 | "const highp vec3 weight = vec3(0.2125, 0.7154, 0.0721);" + 14 | "void main() {" + 15 | "float luminance = dot(texture2D(sTexture, vTextureCoord).rgb, weight);" + 16 | "gl_FragColor = vec4(vec3(luminance), 1.0);" + 17 | "}"; 18 | 19 | public GlGrayScaleFilter() { 20 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlHazeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/05/18. 7 | */ 8 | 9 | public class GlHazeFilter extends GlFilter { 10 | 11 | private static final String FRAGMENT_SHADER = 12 | "precision mediump float;" + 13 | "varying highp vec2 vTextureCoord;" + 14 | "uniform lowp sampler2D sTexture;" + 15 | "uniform lowp float distance;" + 16 | "uniform highp float slope;" + 17 | 18 | "void main() {" + 19 | "highp vec4 color = vec4(1.0);" + 20 | 21 | "highp float d = vTextureCoord.y * slope + distance;" + 22 | 23 | "highp vec4 c = texture2D(sTexture, vTextureCoord);" + 24 | "c = (c - d * color) / (1.0 -d);" + 25 | "gl_FragColor = c;" + // consider using premultiply(c); 26 | "}"; 27 | 28 | private float distance = 0.2f; 29 | private float slope = 0.0f; 30 | 31 | public GlHazeFilter() { 32 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 33 | } 34 | 35 | public float getDistance() { 36 | return distance; 37 | } 38 | 39 | public void setDistance(final float distance) { 40 | this.distance = distance; 41 | } 42 | 43 | public float getSlope() { 44 | return slope; 45 | } 46 | 47 | public void setSlope(final float slope) { 48 | this.slope = slope; 49 | } 50 | 51 | @Override 52 | public void onDraw() { 53 | GLES20.glUniform1f(getHandle("distance"), distance); 54 | GLES20.glUniform1f(getHandle("slope"), slope); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlInvertFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/18. 5 | */ 6 | 7 | public class GlInvertFilter extends GlFilter { 8 | private static final String FRAGMENT_SHADER = 9 | "precision mediump float;" + 10 | "varying vec2 vTextureCoord;" + 11 | "uniform lowp sampler2D sTexture;" + 12 | "void main() {" + 13 | "lowp vec4 color = texture2D(sTexture, vTextureCoord);" + 14 | "gl_FragColor = vec4((1.0 - color.rgb), color.w);" + 15 | "}"; 16 | 17 | public GlInvertFilter() { 18 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlMonochromeFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.opengl.GLES20; 4 | import android.util.Log; 5 | 6 | /** 7 | * Created by sudamasayuki on 2017/05/18. 8 | */ 9 | 10 | public class GlMonochromeFilter extends GlFilter { 11 | 12 | private static final String FRAGMENT_SHADER = 13 | "precision lowp float;" + 14 | 15 | "varying highp vec2 vTextureCoord;" + 16 | "uniform lowp sampler2D sTexture;" + 17 | "uniform float intensity;" + 18 | "uniform vec3 filterColor;" + 19 | 20 | "const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);" + 21 | 22 | "void main() {" + 23 | 24 | "lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);" + 25 | "float luminance = dot(textureColor.rgb, luminanceWeighting);" + 26 | 27 | "lowp vec4 desat = vec4(vec3(luminance), 1.0);" + 28 | 29 | "lowp vec4 outputColor = vec4(" + 30 | "(desat.r < 0.5 ? (2.0 * desat.r * filterColor.r) : (1.0 - 2.0 * (1.0 - desat.r) * (1.0 - filterColor.r)))," + 31 | "(desat.g < 0.5 ? (2.0 * desat.g * filterColor.g) : (1.0 - 2.0 * (1.0 - desat.g) * (1.0 - filterColor.g)))," + 32 | "(desat.b < 0.5 ? (2.0 * desat.b * filterColor.b) : (1.0 - 2.0 * (1.0 - desat.b) * (1.0 - filterColor.b)))," + 33 | "1.0" + 34 | ");" + 35 | 36 | "gl_FragColor = vec4(mix(textureColor.rgb, outputColor.rgb, intensity), textureColor.a);" + 37 | "}"; 38 | private static final String TAG = "GlMonochromeFilter"; 39 | 40 | private float intensity = 1.0f; 41 | private float[] filterColor = new float[]{0.6f, 0.45f, 0.3f}; 42 | 43 | public GlMonochromeFilter() { 44 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 45 | } 46 | 47 | public float getIntensity() { 48 | return intensity; 49 | } 50 | 51 | public void setIntensity(float intensity) { 52 | this.intensity = intensity; 53 | } 54 | 55 | @Override 56 | public void onDraw() { 57 | GLES20.glUniform1f(getHandle("intensity"), intensity); 58 | Log.d(TAG, "onDraw: getHandleMap:"+handleMap.toString()); 59 | // Log.d(TAG, "onDraw: filterColor:"+getHandle("filterColor")); 60 | GLES20.glUniform3fv(getHandle("filterColor"), 1, filterColor, 0); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlSepiaFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/16. 5 | */ 6 | 7 | public class GlSepiaFilter extends GlFilter { 8 | private static final String FRAGMENT_SHADER = 9 | "precision mediump float;" + 10 | "varying vec2 vTextureCoord;" + 11 | "uniform lowp sampler2D sTexture;" + 12 | "const highp vec3 weight = vec3(0.2125, 0.7154, 0.0721);" + 13 | "void main() {" + 14 | " vec4 FragColor = texture2D(sTexture, vTextureCoord);\n" + 15 | " gl_FragColor.r = dot(FragColor.rgb, vec3(.393, .769, .189));\n" + 16 | " gl_FragColor.g = dot(FragColor.rgb, vec3(.349, .686, .168));\n" + 17 | " gl_FragColor.b = dot(FragColor.rgb, vec3(.272, .534, .131));\n" + 18 | "}"; 19 | 20 | public GlSepiaFilter() { 21 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlSphereRefractionFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/05/18. 7 | */ 8 | 9 | public class GlSphereRefractionFilter extends GlFilter { 10 | 11 | private static final String FRAGMENT_SHADER = 12 | "precision mediump float;" + 13 | 14 | "varying vec2 vTextureCoord;" + 15 | "uniform lowp sampler2D sTexture;" + 16 | "uniform highp vec2 center;" + 17 | "uniform highp float radius;" + 18 | "uniform highp float aspectRatio;" + 19 | "uniform highp float refractiveIndex;" + 20 | 21 | "void main() {" + 22 | "highp vec2 textureCoordinateToUse = vec2(vTextureCoord.x, (vTextureCoord.y * aspectRatio + 0.5 - 0.5 * aspectRatio));" + 23 | "highp float distanceFromCenter = distance(center, textureCoordinateToUse);" + 24 | "lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);" + 25 | 26 | "distanceFromCenter = distanceFromCenter / radius;" + 27 | 28 | "highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);" + 29 | "highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));" + 30 | 31 | "highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);" + 32 | 33 | "gl_FragColor = texture2D(sTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;" + 34 | "}"; 35 | 36 | private float centerX = 0.5f; 37 | private float centerY = 0.5f; 38 | private float radius = 0.5f; 39 | private float aspectRatio = 1.0f; 40 | private float refractiveIndex = 0.71f; 41 | 42 | public GlSphereRefractionFilter() { 43 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 44 | } 45 | 46 | public void setCenterX(float centerX) { 47 | this.centerX = centerX; 48 | } 49 | 50 | public void setCenterY(float centerY) { 51 | this.centerY = centerY; 52 | } 53 | 54 | public void setRadius(float radius) { 55 | this.radius = radius; 56 | } 57 | 58 | public void setAspectRatio(float aspectRatio) { 59 | this.aspectRatio = aspectRatio; 60 | } 61 | 62 | public void setRefractiveIndex(float refractiveIndex) { 63 | this.refractiveIndex = refractiveIndex; 64 | } 65 | 66 | ////////////////////////////////////////////////////////////////////////// 67 | 68 | @Override 69 | public void onDraw() { 70 | GLES20.glUniform2f(getHandle("center"), centerX, centerY); 71 | GLES20.glUniform1f(getHandle("radius"), radius); 72 | GLES20.glUniform1f(getHandle("aspectRatio"), aspectRatio); 73 | GLES20.glUniform1f(getHandle("refractiveIndex"), refractiveIndex); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlVignetteFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | import android.opengl.GLES20; 4 | 5 | /** 6 | * Created by sudamasayuki on 2017/05/18. 7 | */ 8 | 9 | public class GlVignetteFilter extends GlFilter { 10 | 11 | private static final String FRAGMENT_SHADER = 12 | "precision mediump float;" + 13 | 14 | "varying vec2 vTextureCoord;" + 15 | "uniform lowp sampler2D sTexture;" + 16 | 17 | "uniform lowp vec2 vignetteCenter;" + 18 | "uniform lowp vec3 vignetteColor;" + 19 | "uniform highp float vignetteStart;" + 20 | "uniform highp float vignetteEnd;" + 21 | 22 | "void main() {" + 23 | "lowp vec3 rgb = texture2D(sTexture, vTextureCoord).rgb;" + 24 | "lowp float d = distance(vTextureCoord, vec2(vignetteCenter.x, vignetteCenter.y));" + 25 | "lowp float percent = smoothstep(vignetteStart, vignetteEnd, d);" + 26 | "gl_FragColor = vec4(mix(rgb.x, vignetteColor.x, percent), mix(rgb.y, vignetteColor.y, percent), mix(rgb.z, vignetteColor.z, percent), 1.0);" + 27 | "}"; 28 | 29 | private float vignetteCenterX = 0.5f; 30 | private float vignetteCenterY = 0.5f; 31 | private float[] vignetteColor = new float[]{0f, 0f, 0f}; 32 | private float vignetteStart = 0.2f; 33 | private float vignetteEnd = 0.85f; 34 | 35 | public GlVignetteFilter() { 36 | super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER); 37 | } 38 | 39 | 40 | public float getVignetteStart() { 41 | return vignetteStart; 42 | } 43 | 44 | public void setVignetteStart(final float vignetteStart) { 45 | this.vignetteStart = vignetteStart; 46 | } 47 | 48 | public float getVignetteEnd() { 49 | return vignetteEnd; 50 | } 51 | 52 | public void setVignetteEnd(final float vignetteEnd) { 53 | this.vignetteEnd = vignetteEnd; 54 | } 55 | 56 | ////////////////////////////////////////////////////////////////////////// 57 | 58 | @Override 59 | public void onDraw() { 60 | GLES20.glUniform2f(getHandle("vignetteCenter"), vignetteCenterX, vignetteCenterY); 61 | GLES20.glUniform3fv(getHandle("vignetteColor"), 1, vignetteColor, 0); 62 | 63 | GLES20.glUniform1f(getHandle("vignetteStart"), vignetteStart); 64 | GLES20.glUniform1f(getHandle("vignetteEnd"), vignetteEnd); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/preview/filter/GlWeakPixelInclusionFilter.java: -------------------------------------------------------------------------------- 1 | package com.video.process.preview.filter; 2 | 3 | /** 4 | * Created by sudamasayuki on 2017/05/18. 5 | */ 6 | 7 | public class GlWeakPixelInclusionFilter extends GlThreex3TextureSamplingFilter { 8 | 9 | private static final String FRAGMENT_SHADER = 10 | "precision lowp float;\n" + 11 | 12 | "uniform lowp sampler2D sTexture;\n" + 13 | 14 | "varying vec2 textureCoordinate;\n" + 15 | "varying vec2 leftTextureCoordinate;\n" + 16 | "varying vec2 rightTextureCoordinate;\n" + 17 | 18 | "varying vec2 topTextureCoordinate;\n" + 19 | "varying vec2 topLeftTextureCoordinate;\n" + 20 | "varying vec2 topRightTextureCoordinate;\n" + 21 | 22 | "varying vec2 bottomTextureCoordinate;\n" + 23 | "varying vec2 bottomLeftTextureCoordinate;\n" + 24 | "varying vec2 bottomRightTextureCoordinate;\n" + 25 | 26 | "void main() {\n" + 27 | "float bottomLeftIntensity = texture2D(sTexture, bottomLeftTextureCoordinate).r;" + 28 | "float topRightIntensity = texture2D(sTexture, topRightTextureCoordinate).r;" + 29 | "float topLeftIntensity = texture2D(sTexture, topLeftTextureCoordinate).r;" + 30 | "float bottomRightIntensity = texture2D(sTexture, bottomRightTextureCoordinate).r;" + 31 | "float leftIntensity = texture2D(sTexture, leftTextureCoordinate).r;" + 32 | "float rightIntensity = texture2D(sTexture, rightTextureCoordinate).r;" + 33 | "float bottomIntensity = texture2D(sTexture, bottomTextureCoordinate).r;" + 34 | "float topIntensity = texture2D(sTexture, topTextureCoordinate).r;" + 35 | "float centerIntensity = texture2D(sTexture, textureCoordinate).r;" + 36 | 37 | "float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity;" + 38 | "float sumTest = step(1.5, pixelIntensitySum);" + 39 | "float pixelTest = step(0.01, centerIntensity);" + 40 | 41 | "gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0);" + 42 | "}"; 43 | 44 | public GlWeakPixelInclusionFilter() { 45 | super(FRAGMENT_SHADER); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/surface/MagicJni.java: -------------------------------------------------------------------------------- 1 | package com.video.process.surface; 2 | 3 | public class MagicJni { 4 | static { 5 | System.loadLibrary("MagicBeautify"); 6 | } 7 | 8 | public static native void glReadPixels(int x, int y, int width, int height, int format, int type); 9 | } 10 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/surface/VideoProcessConfig.java: -------------------------------------------------------------------------------- 1 | package com.video.process.surface; 2 | 3 | import com.video.process.preview.filter.GlFilterConfig; 4 | 5 | import java.io.Serializable; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class VideoProcessConfig implements Serializable { 10 | public String srcMediaPath; 11 | public String outMediaPath; 12 | 13 | public List filterConfigList = new ArrayList<>(); 14 | 15 | public VideoProcessConfig(String srcMediaPath, String outMediaPath) { 16 | this.srcMediaPath = srcMediaPath; 17 | this.outMediaPath = outMediaPath; 18 | } 19 | 20 | public List getFilterConfigList() { 21 | return filterConfigList; 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/thread/IVideoEncodeThread.java: -------------------------------------------------------------------------------- 1 | package com.video.process.thread; 2 | 3 | import android.view.Surface; 4 | 5 | import java.util.concurrent.CountDownLatch; 6 | 7 | public interface IVideoEncodeThread { 8 | Surface getSurface(); 9 | CountDownLatch getEglContextLatch(); 10 | } 11 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/utils/LogUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.process.utils; 2 | 3 | import android.util.Log; 4 | 5 | public class LogUtils { 6 | private static final String TAG = "VideoEdit"; 7 | private static final boolean VERBOSE = false; 8 | private static final boolean DEBUG = false; 9 | private static final boolean INFO = true; 10 | private static final boolean WARIN = true; 11 | private static final boolean ERROR = true; 12 | 13 | public static void v(String msg) { 14 | if (VERBOSE) { 15 | Log.v(TAG, msg); 16 | } 17 | } 18 | 19 | public static void v(String tag, String msg) { 20 | if (VERBOSE) { 21 | Log.v(tag, msg); 22 | } 23 | } 24 | 25 | public static void d(String msg) { 26 | if (DEBUG) { 27 | Log.d(TAG, msg); 28 | } 29 | } 30 | 31 | public static void d(String tag, String msg) { 32 | if (DEBUG) { 33 | Log.d(tag, msg); 34 | } 35 | } 36 | 37 | public static void i(String msg) { 38 | if (INFO) { 39 | Log.i(TAG, msg); 40 | } 41 | } 42 | 43 | public static void i(String tag, String msg) { 44 | if (INFO) { 45 | Log.i(tag, msg); 46 | } 47 | } 48 | 49 | public static void w(String msg) { 50 | if (WARIN) { 51 | Log.w(TAG, msg); 52 | } 53 | } 54 | 55 | public static void w(String tag, String msg) { 56 | if (WARIN) { 57 | Log.w(tag, msg); 58 | } 59 | } 60 | 61 | public static void e(String msg) { 62 | if (ERROR) { 63 | Log.e(TAG, msg); 64 | } 65 | } 66 | 67 | public static void e(String tag, String msg) { 68 | if (ERROR) { 69 | Log.e(tag, msg); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/utils/ScreenUtils.java: -------------------------------------------------------------------------------- 1 | package com.video.process.utils; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | 6 | public class ScreenUtils { 7 | 8 | public static int getScreenWidth(Context context) { 9 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 10 | return displayMetrics.widthPixels; 11 | } 12 | 13 | public static int getScreenHeight(Context context) { 14 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 15 | return displayMetrics.heightPixels; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/utils/VideoCustomException.java: -------------------------------------------------------------------------------- 1 | package com.video.process.utils; 2 | 3 | public class VideoCustomException extends Exception { 4 | 5 | public static final int CLIP_VIDEO_TIMERANGE_ERROR = 1; 6 | public static final int CLIP_VIDEO_OUT_OF_RANGE = 2; 7 | public static final int MEDIA_EXTRACTOR_DATASOURCE_FAILED = 3; 8 | public static final int MEDIA_MUXER_INSTANCE_FAILED = 4; 9 | public static final int MEDIA_HAS_NO_VIDEO = 5; 10 | public static final int SRC_VIDEO_FILE_ERROR = 6; 11 | public static final int SRC_VIDEO_FILE_ERROR2 = 7; 12 | public static final int SRC_VIDEO_FILE_ERROR3 = 8; 13 | 14 | private int mErr; 15 | private Throwable mException; 16 | 17 | public VideoCustomException(int err, Throwable e) { 18 | mErr = err; 19 | mException = e; 20 | } 21 | 22 | public String toString() { 23 | return "VideoCustomException[ErrCode=" + mErr+", ErrMsg="+mException.getMessage()+"]"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/java/com/video/process/utils/WorkThreadHandler.java: -------------------------------------------------------------------------------- 1 | package com.video.process.utils; 2 | 3 | import android.os.Process; 4 | 5 | import java.util.concurrent.BlockingQueue; 6 | import java.util.concurrent.Callable; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Future; 9 | import java.util.concurrent.LinkedBlockingQueue; 10 | import java.util.concurrent.ThreadFactory; 11 | import java.util.concurrent.ThreadPoolExecutor; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | public class WorkThreadHandler { 15 | private static final int CPU_COUNT = 16 | Runtime.getRuntime().availableProcessors(); 17 | private static final int CORE_POOL_SIZE = CPU_COUNT + 1; 18 | private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; 19 | private static final int KEEP_ALIVE = 1; 20 | private static final int QUEUE_SIZE = 2 ^ CPU_COUNT; 21 | 22 | private static class MediaWorkerThreadFactory implements ThreadFactory { 23 | public Thread newThread(Runnable r) { return new MediaWorkerThread(r); } 24 | } 25 | 26 | private static class MediaWorkerThread extends Thread { 27 | public MediaWorkerThread(Runnable r) { 28 | super(r, "vivo_media_worker_pool_thread"); 29 | } 30 | 31 | @Override 32 | public void run() { 33 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 34 | long startTime = System.currentTimeMillis(); 35 | super.run(); 36 | long endTime = System.currentTimeMillis(); 37 | LogUtils.i("WorkThreadHandler execution time: " + (endTime - startTime)); 38 | } 39 | } 40 | 41 | private static final BlockingQueue sThreadPoolWorkQueue = 42 | new LinkedBlockingQueue(QUEUE_SIZE); 43 | private static final ExecutorService sThreadPoolExecutor = 44 | new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, 45 | TimeUnit.SECONDS, sThreadPoolWorkQueue, 46 | new MediaWorkerThreadFactory(), 47 | new ThreadPoolExecutor.DiscardOldestPolicy()); 48 | 49 | public static Future submitCallbackTask(Callable task) { 50 | return sThreadPoolExecutor.submit(task); 51 | } 52 | 53 | public static Future submitRunnableTask(Runnable task) { 54 | return sThreadPoolExecutor.submit(task); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/jni/MagicJni.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | JNIEXPORT void JNICALL 9 | Java_com_video_process_egl_MagicJni_glReadPixels( 10 | JNIEnv *env, jclass cls, jint x, jint y, jint width, jint height, 11 | jint format, jint type) { 12 | glReadPixels(x, y, width, height, format, type, 0); 13 | } 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /videoEditSdk/src/main/res/drawable/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JeffMony/MediaEditSDK/35a87045e000857f8f33c04528b03c96028a2582/videoEditSdk/src/main/res/drawable/image1.jpg -------------------------------------------------------------------------------- /videoEditSdk/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | epf 3 | 4 | --------------------------------------------------------------------------------