All Projects → arthur3486 → ARVI

arthur3486 / ARVI

Licence: Apache-2.0 license
Android library designed to simplify the implementation of the video autoplay in the RecyclerView

Programming Languages

java
68154 projects - #9 most used programming language
kotlin
9241 projects

Projects that are alternatives of or similar to ARVI

Sherlockadapter
一个万能的封装了RecyclerView.Adapter的功能库。
Stars: ✭ 186 (+169.57%)
Mutual labels:  adapter, recyclerview
Dsladapter
🔥 Kotlin时代的Adapter, Dsl 的形式使用 RecyclerView.Adapter, 支持折叠展开, 树结构,悬停,情感图状态切换, 加载更多, 多类型Item,侧滑菜单等
Stars: ✭ 231 (+234.78%)
Mutual labels:  adapter, recyclerview
Easyadapter
This project demonstrates simple approach for implementation complex lists, based on RecyclerView.
Stars: ✭ 187 (+171.01%)
Mutual labels:  adapter, recyclerview
Kotlin Adapter
🔥 RecyclerView,AbsListView适配器, 支持多种视图样式, 支持吸顶、侧滑删除、拖拽效果
Stars: ✭ 132 (+91.3%)
Mutual labels:  adapter, recyclerview
Modular2Recycler
Modular²Recycler is a RecyclerView.Adapter that is modular squared.
Stars: ✭ 72 (+4.35%)
Mutual labels:  adapter, recyclerview
Recyclerviewadapter
A RecyclerView Adapter that support load more and add headerview
Stars: ✭ 141 (+104.35%)
Mutual labels:  adapter, recyclerview
Commonadapter
一个适用于ListView/GridView/RecyclerView的Adapter库,简化大量重复代码,支持多种布局,可自定义图片加载的实现。
Stars: ✭ 219 (+217.39%)
Mutual labels:  adapter, recyclerview
Grouprecyclerviewadapter
可增删改查、可动画展开收起、可吸附悬浮动态可配置的分组列表
Stars: ✭ 41 (-40.58%)
Mutual labels:  adapter, recyclerview
MultiTypeAdapter
RecyclerView通用多类型适配器MultiTypeAdapter,以布局文件为单位更细粒度的条目复用。
Stars: ✭ 18 (-73.91%)
Mutual labels:  adapter, recyclerview
AutoPlayVideoRecyclerView
Android library to auto play video from url in Recyclerview.
Stars: ✭ 44 (-36.23%)
Mutual labels:  recyclerview, autoplay
Sectionedrecyclerviewadapter
An Adapter that allows a RecyclerView to be split into Sections with headers and/or footers. Each Section can have its state controlled individually.
Stars: ✭ 1,659 (+2304.35%)
Mutual labels:  adapter, recyclerview
PrimeAdapter
PrimeAdapter makes working with RecyclerView easier.
Stars: ✭ 54 (-21.74%)
Mutual labels:  adapter, recyclerview
Poweradapter
Adapter for RecyclerView(only 21KB).RecyclerView万能适配器(仅21KB)
Stars: ✭ 112 (+62.32%)
Mutual labels:  adapter, recyclerview
Easyadapter
Android 轻量级适配器,简化使用,适应所有的AbsListView、RecyclerView。支持HeaderView与FooterView~
Stars: ✭ 160 (+131.88%)
Mutual labels:  adapter, recyclerview
Recyclerviewpresenter
RecyclerView Adapter Library with different models and different layouts as convenient as possible.
Stars: ✭ 86 (+24.64%)
Mutual labels:  adapter, recyclerview
Multiselectadapter
MultiSelectAdapter可以让你的Adapter快速实现多选和批量操作
Stars: ✭ 195 (+182.61%)
Mutual labels:  adapter, recyclerview
Google Books Android Viewer
Android library to bridge between RecyclerView and sources like web page or database. Includes demonstrator (Google Books viewer)
Stars: ✭ 37 (-46.38%)
Mutual labels:  adapter, recyclerview
Flagchatadapter
FlagChatAdapter is easy to implement enchanting recycler view adapter. Just extend your adapter with FlagChatAdapter, impliment some methods and voila! You have got the most beautiful looking chat on your phone. Zero boilerplate code, just put your variables in the right direction.
Stars: ✭ 39 (-43.48%)
Mutual labels:  adapter, recyclerview
InstantRecyclerView
A library that helps to implement a complex list with RecyclerView.(RecyclerView使用的封装与优化,帮助你快速利用RecyclerView构建复杂列表)
Stars: ✭ 22 (-68.12%)
Mutual labels:  adapter, recyclerview
Android-hls
最近公司产品需要,调研hls(m3u8) aes-128 解密播放 . 分析 51Cto, 慕课
Stars: ✭ 73 (+5.8%)
Mutual labels:  player, exoplayer

ARVI - Autoplayable RecyclerView Items

ExoPlayer-based Android library that makes the implementation of the autoplayable RecyclerView video items an easy task

ARVI will enable you to make your feeds more interactive and appealing to your end users without the need to spend a lot of your valuable time on the implementation.

Download License Platform Android Arsenal

Contents

Demo (YouTube)

YouTube Video

Getting Started

Prerequisites

1. Make sure that you've added the jcenter() repository to your top-level build.gradle file.

buildscript {
    //...
    repositories {
        //...
        jcenter()
    }
    //...
}

2. Enable the jetifier and androidX support in the top-level gradle.properties file.

//...
android.enableJetifier=true
android.useAndroidX=true
//....

3. Update your compileSdkVersion in the module-level build.gradle file to 28+.

//...
android {
    //...
    compileSdkVersion 28
    //...
}
//...

4. Replace your com.android.support.appcompat.* dependency with the new androidx.appcompat.* alternative.

//...
dependencies {
    //...
    implementation "androidx.appcompat:appcompat:1.0.1"
    //...
}
//...

5. Add the ExoPlayer dependency to the module-level build.gradle file.

//...
dependencies {
    //...
    implementation "com.google.android.exoplayer:exoplayer:2.9.2"
    //...
}
//...

ARVI Dependencies

ARVI is comprised of several library modules, namely:

  • arvi - core functionality (Required)
  • arvi-adapster - Adapster adaptation (Optional)
  • arvi-ktx - common extensions (Optional)
  • arvi-utils - common utils and helpers (Optional)

The basic implementation would have to include the core module

Latest version: Download

implementation "com.arthurivanets.arvi:arvi:X.Y.Z"

Which should be added to your module-level build.gradle file.

ext {
    //...
    arviLibraryVersion = "1.0.0"
}

dependencies {
    //...
    implementation "com.arthurivanets.arvi:arvi:$arviLibraryVersion"
}

After that you can proceed with further implementation.

See: Basic Implementation and Adapster-based Implementation

Basic Implementation

Basic implementation consists of 3 straightforward steps, which include the proper handling of the system memory claims, creation of the playable Item View Holder, and the incorporation of the Playable Items Container.

The steps you need to take:

1. Ensure the proper release of the active players when the application goes into background (System Memory Claims)

Kotlin (click to expand)

Basic

//...
import com.arthurivanets.arvi.PlayerProviderImpl

class ArviApplication : Application() {

    //...

    override fun onTrimMemory(level : Int) {
        super.onTrimMemory(level)

        if(level >= TRIM_MEMORY_BACKGROUND) {
            PlayerProviderImpl.getInstance(this).release()
        }
    }

    //...

}

With arvi-ktx

//...
import com.arthurivanets.arvi.ktx.playerProvider

class ArviApplication : Application() {

    //...

    override fun onTrimMemory(level : Int) {
        super.onTrimMemory(level)

        if(level >= TRIM_MEMORY_BACKGROUND) {
            playerProvider.release()
        }
    }

    //...

}


Java (click to expand)

//...
import com.arthurivanets.arvi.PlayerProviderImpl;

public final class YourApplication extends Application {

    //...

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);

        if(level >= TRIM_MEMORY_BACKGROUND) {
            PlayerProviderImpl.getInstance(this).release();
        }
    }
    
    //...

}


2. Implement your Item's ViewHolder based on the PlayableItemViewHolder

IMPORTANT: Your ViewHolder's layout.xml file must contain a PlayerView child with an id @id/player_view.

See: BasicVideoItemViewHolder and item_video.xml

Kotlin (click to expand)

class BasicVideoItemViewHolder(
    parent : ViewGroup,
    itemView : View
) : PlayableItemViewHolder(parent, itemView) {

    //...

    override fun getUrl() : String {
        return "video_url..."
    }
    
    //...

}


Java (click to expand)

public final class BasicVideoItemViewHolder extends PlayableItemViewHolder {

    //...

    @Override
    public final String getUrl() {
        return "video_url...";
    }

    //...

}


3. Replace the regular RecyclerView with the PlayableItemsRecyclerView

IMPORTANT: PlayableItemsRecyclerView should be bound to the lifecycle of the Activity/Fragment (Activity/Fragment lifecycle events should be propagated to the PlayableItemsRecyclerView) in order to ensure the correct handling of the item video playback.

See: PlayableItemsRecyclerView, BasicVideoItemsRecyclerViewAdapter, BasicVideosFragment and fragment_videos.xml

Kotlin (click to expand)

class BasicVideosFragment : BaseFragment() {

    //...

    override fun init(savedInstanceState : Bundle?) {
        with(recyclerView) {
	    // PlayableItemRecyclerView configuration
            setPlaybackTriggeringStates(
                PlayableItemsContainer.PlaybackTriggeringState.IDLING,
                PlayableItemsContainer.PlaybackTriggeringState.DRAGGING
            )

            autoplayMode = PlayableItemsContainer.AutoplayMode.ONE_AT_A_TIME
            adapter = BasicVideoItemsRecyclerViewAdapter(
                context = context!!,
                items = VideoProvider.getVideos(count = 100, mute = true).toMutableList(),
                arviConfig = Config.Builder()
                    .cache(ExoPlayerUtils.getCache(context!!))
                    .build()
            )
        }
    }
    
    //...

    override fun onResume() {
        super.onResume()

        recyclerView.onResume()
    }

    override fun onPause() {
        super.onPause()

        recyclerView.onPause()
    }

    override fun onDestroy() {
    	recyclerView?.onDestroy()
	
        super.onDestroy()
    }
    
    //...

}


Java (click to expand)

public final class BasicVideosFragment extends BaseFragment {

    //...

    @Override
    public void init(Bundle savedInstanceState) {
        mRecyclerView.setPlaybackTriggeringStates(
            PlayableItemsContainer.PlaybackTriggeringState.IDLING,
            PlayableItemsContainer.PlaybackTriggeringState.DRAGGING
        );
        mRecyclerView.setAutoplayMode(PlayableItemsContainer.AutoplayMode.ONE_AT_A_TIME);
        mRecyclerView.setAdapter(new BasicVideoItemsRecyclerViewAdapter(
            context,
            VideoProvider.getVideos(100, true),
            new Config.Builder()
                .cache(ExoPlayerUtils.getCache(context))
                .build()
        ));
    }
    
    //...

    @Override
    public void onResume() {
        super.onResume();

        mRecyclerView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();

        mRecyclerView.onPause();
    }

    @Override
    public void onDestroy() {
        mRecyclerView.onDestroy();
    
        super.onDestroy();
    }
    
    //...

}


For more advanced use cases

See: Advanced Use Cases

Adapster-based Implementation

Adapster-based implementation requires both the official Adapster and arvi-adapster module dependencies.

Latest ARVI version: Download

implementation "com.arthurivanets.arvi:arvi-adapster:X.Y.Z"

While the implementation itself shares most of the steps with the Basic Implementation, one of the things that should be taken into account is the fact that the implementation of your Item ViewHolder should be based on the AdapsterPlayableItemViewHolder instead of the PlayableItemViewHolder.

Kotlin (click to expand)

//...
import com.arthurivanets.arvi.adapster.AdapsterPlayableItemViewHolder

class VideoItemViewHolder(
    parent : ViewGroup,
    itemView : View,
    private val resources : VideoItemResources?
) : AdapsterPlayableItemViewHolder<Video>(parent, itemView) {

    //...

    override fun getUrl() : String {
        return "video_url..."
    }
    
    //...

}


Java (click to expand)

//...
import com.arthurivanets.arvi.adapster.AdapsterPlayableItemViewHolder;

public final class VideoItemViewHolder extends AdapsterPlayableItemViewHolder<Video> {

    //...
    
    @Override
    public final String getUrl() {
        return "video_url...";
    }
    
    //...

}


See: VideoItemsRecyclerViewAdapter, AdapsterVideosFragment, AdapsterPlayableItemViewHolder and VideoItemViewHolder

For more advanced use cases

See: Advanced Use Cases

Advanced Use Cases

Sometimes you require something more than a basic implementation, whether it's an ability to enable the caching of your videos or a way to authorize your HTTP Video requests, you name it; for that reason a list of the most common advanced use cases has been compiled.

Most common advanced use cases include, but not limited to:

1. Video Caching

In order to enable the video caching you should provide an instance of the ExoPlayer Cache via the ARVI Config to your Item ViewHolders, and then use the provided Config within each corresponding Item ViewHolder.

Kotlin (click to expand)

//...
import com.arthurivanets.arvi.Config

class BasicVideoItemViewHolder(
    parent : ViewGroup,
    itemView : View,
    val arviConfig : Config
) : PlayableItemViewHolder(parent, itemView) {

    //...

    override fun getUrl() : String {
        return "video_url..."
    }
    
    override fun getConfig() : Config {
        return arviConfig
    }
    
    //...

}

Adapster-based

//...
import com.arthurivanets.arvi.adapster.AdapsterPlayableItemViewHolder

class VideoItemViewHolder(
    parent : ViewGroup,
    itemView : View,
    private val resources : VideoItemResources?
) : AdapsterPlayableItemViewHolder<Video>(parent, itemView) {

    //...

    override fun getUrl() : String {
        return "video_url..."
    }
    
    override fun getConfig() : Config {
        return (resources?.arviConfig ?: super.getConfig())
    }
    
    //...

}


Java (click to expand)

//...
import com.arthurivanets.arvi.Config;

public final class BasicVideoItemViewHolder extends PlayableItemViewHolder {

    //...

    @Override
    public final String getUrl() {
        return "video_url...";
    }
    
    @Override
    public final Config getConfig() {
        return arviConfig;
    }
    
    //...

}

Adapster-based

//...
import com.arthurivanets.arvi.adapster.AdapsterPlayableItemViewHolder;

public final class VideoItemViewHolder extends AdapsterPlayableItemViewHolder<Video> {

    //...

    @Override
    public final String getUrl() {
        return "video_url...";
    }
    
    @Override
    public final Config getConfig() {
        return resources.arviConfig;
    }
    
    //...

}


The general ExoPlayer Cache instance can be easily created using the utility extension methods found in the ArviExtensions of the arvi-ktx module, or you can resort to your own ExoPlayer Cache instance creation approach; choose the approach that fits your requirements the best.

For more details

See: BasicVideosFragment, BasicVideoItemsRecyclerViewAdapter, BasicVideoItemViewHolder, AdapsterVideosFragment, VideoItemsRecyclerViewAdapter, VideoItem, VideoItemViewHolder, VideoItemResources, Config, ArviExtensions, Cache

2. HTTP Video Request Authorization

In cases when your video requests require authorization, you can use the RequestAuthorizer to provide the necessary auth token whenever the player requests it. The created RequestAuthorizer should be associated with the ArviHttpDataSourceFactory and passed around in the ARVI Config object.

RequestAuthorizer

Kotlin (click to expand)

//...
import com.arthurivanets.arvi.player.datasource.RequestAuthorizer

class ArviRequestAuthorizer(private val authTokenProvider : AuthTokenProvider) : RequestAuthorizer {

    override fun getAuthorization() : String {
        return "Bearer ${authTokenProvider.getAuthToken()}"
    }

}


Java (click to expand)

//...
import com.arthurivanets.arvi.player.datasource.RequestAuthorizer;

public final class ArviRequestAuthorizer extends RequestAuthorizer {

    //...

    @Override
    public final String getAuthorization() {
        return ("Bearer " + authTokenProvider.getAuthToken());
    }

}


ARVI Config

Kotlin (click to expand)

//...
val config = Config.Builder()
    .dataSourceFactory(
        ArviHttpDataSourceFactory(context.playerProvider.libraryName).apply {
            setConnectTimeout(REQUEST_CONNECT_TIMEOUT_IN_MILLIS)
            setReadTimeout(REQUEST_READ_TIMEOUT_IN_MILLIS)
            
            // Your request authorizer
            setRequestAuthorizer(ArviRequestAuthorizer(...))
        }
    )
    .build()


Java (click to expand)

//...
final ArviHttpDataSourceFactory dataSourceFactory = new ArviHttpDataSourceFactory(PlayerProviderImpl.getInstance(context).getLibraryName());
dataSourceFactory.setConnectTimeout(REQUEST_CONNECT_TIMEOUT_IN_MILLIS);
dataSourceFactory.setReadTimeout(REQUEST_READ_TIMEOUT_IN_MILLIS);

// Your request authorizer
dataSourceFactory.setRequestAuthorizer(new ArviRequestAuthorizer(...));

// the final Config
final Config config = new Config.Builder()
    .dataSourceFactory(dataSourceFactory)
    .build();


See: RequestAuthorizer, ArviHttpDataSourceFactory, Config

3. ViewHolder Playback Control

All Playable Item ViewHolders are capable of controlling almost every aspect of the corresponding playback, thus giving you more power in terms of the actual implementation.

For more details on what possibilities the Playable gives you

See: Playable

4. ARVI Players

All the Players created using the PlayerProviderImpl can be used as stand alone players, as they are totally independent entities, the only thing to remember here is that you should properly handle the player binding/unbinding events to avoid the potential memory leaks and other related issues.

See: Player, PlayerProvider, PlayerProviderImpl

Contribution

See the CONTRIBUTING.md file.

Hall of Fame

Owly

Using ARVI in your app and want it to get listed here? Email me at [email protected]!

License

ARVI is licensed under the Apache 2.0 License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].