Skip to content

Latest commit

 

History

History
530 lines (367 loc) · 35.9 KB

CHANGELOG.md

File metadata and controls

530 lines (367 loc) · 35.9 KB

Changelog

3.7.0.2010003 (2020/02/15)

This release is to support ExoPlayer 2.10.3. This will be the last version of ExoPlayer 2.10.x to be supported. From next release, Toro will support ExoPlayer 2.11.2 and newer.

  • [Update]: ExoPlayer to 2.10.3. Related classes are updated with backward compatibility and some deprecation to Toro implementations.
  • [Update]: Demo for mopub now uses mopub 5.10.0 for Android.
  • [Update]: AdsExoPlayerViewHelper now requires AdsLoader.AdViewProvider instead of ViewGroup as adsContainer. This is to update with ExoPlayer 2.10.3.
  • [Update]: Config construction now allow to pass Context, and creating new Config with Context is recommended way.

Some other changes may require migration effort, please feel free to create Github Issues.

3.7.0.2905-A1 (2019/10/18)

This release is a middle-stage release to insist the full release of 3.7.0-2010005 3.7.0-2010003.

This alpha release contains the following significant changes:

  • Migrate to AndroidX. Toro will now depends on AndroidX and other latest Jetpack libraries.
  • Update ExoPlayer to 2.9.5. As said, the target will be ExoPlayer 2.10.5 2.10.3. Since ExoPlayer 2.10.x is update with many things may not work well with 2.9.x, this release can also be helpful for those who depends on 2.9.5 for long term.
  • ToroPlayerHelper and Playable interface now have setPlaybackInfo method to support manual PlaybackInfo setup. Default implementation classes are updated with this change.

3.6.2.2903 (2019/01/18)

Happy New Year 2019, the first release this year just to make the lib work with latest ExoPlayer.

  • [Update] Update to ExoPlayer 2.9.3, Android Studio 3.3 final.

3.6.2.2804 (2018/12/16)

  • [Update] Update to ExoPlayer 2.8.4, Android 28 and Support Libraries 28, Android Studio 3.3 RC2.

  • [Update] Add onFirstFrameRendered() to ToroPlayer.EventListener. The method is called when the video is first rendered to the View. This is a signal to the client to hide the thumbnail view for example. Implementation of Helper class is responsible for calling this callback. When used with MediaPlayer this will only called on Android 17 and above.

  • [Update] Add CopyOnWriteArraySet implementation for listeners of ToroPlayer.

  • [Update] toro_exo_player_view has a change in layout structure: the ProgressBar is brought to the front, in front of exo_overlay FrameLayout.

  • [Change/Breaking] ToroPlayerHelper#initialize(Container, PlaybackInfo) is now final. Any implementation that override this method should be updated. The recommended way is to override the ToroPlayerHelper#initialize(PlaybackInfo) only.

  • [Demo App] Better build config for app module. Proguard is included to demonstrate real life scenario. APK of this demo is included in the release tag.

3.6.1.2802 (2018/09/11)

  • [Fix] Fix a bug that allow ExoPlayer instance to reuse VolumeInfo of a Player for other Player.

3.6.0.2802 (2018/08/27)

  • [Update] Now use ExoPlayer 2.8.2

  • [Update] Version name format to indicate which version of ExoPlayer is supported.

  • [Update] Container#savePlaybackInfo now accepts Nullable PlaybackInfo but it will be ignored.

  • [Change/Breaking] Config (in toro extension for exoplayer) no longer use array of DrmSessionManager.

  • [Change/Breaking] ToroExo#createDrmSessionManager no longer requires Handler parameter.

  • [New] Introduce ToroPlayer.OnErrorListener and add/remove methods for it.

  • [New] ToroControlView now also available for toro-exoplayer. Clients can simply use PlayerView with 'player_layout_id' to be @layout/toro_exo_player_view. ToroControlView is an extension of PlayerControlView that is empowered with the ability to change Volume and mute/un-mute switching.

  • [New/Beta] Add new built-in PlayerSelector: PressablePlayerSelector which is also a View.OnLongClickListener. This can be used when client allows user to long-press to a ToroPlayer to make it starts playing.

  • [New/Beta] Add new ExoPlayerDispatcher which is a ControlDispatcher for ExoPlayer PlayerControlView. Use this with PlayerView to allow user to control the playback using the UI. ExoPlayerDispatcher connects to Container to correctly update the playback position.

  • [New/Beta] Add AdsExoPlayerViewHelper that integrate with ExoPlayer IMA Extension.

  • [New/Beta] Add AdsPlayable that integrate with ExoPlayer IMA Extension. This Playable can be used together with AdsExoPlayerViewHelper or standalone.

3.5.0 (2018/05/18) 3.5.2 (2018/05/21)

README: Release 3.5.0 and 3.5.1 was not correctly distributed to jcenter (3.5.1 was an attempt to fix 3.5.0 but also failed).

TL,DR: From Toro 3.5.0, client can actively prepare a PlaybackInfo for ToroPlayer by its order, using the newly added Container$Initializer interface.

Custom initial PlaybackInfo sample:

container.setPlayerInitializer(order -> {
  VolumeInfo volumeInfo = new VolumeInfo(true, 0.75f); // mute by default, but will be 0.75 when un-mute
  return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo);
});

Toro is also updated with improved PlaybackInfo in-memory caching mechanism, giving client better performance and correctness.

DETAILS

  • Toro is now developed using Android Studio 3.2

  • ExoPlayer extension now depends on ExoPlayer 2.7.3. (2.8.0 is a breaking change and will be support in next major release).

  • ToroPlayer:

    • ToroPlayer#initialize(Container, PlaybackInfo) now has non-null PlaybackInfo (was null-able).
    • ToroPlayerHelper#initialize(Container, PlaybackInfo) now has non-null PlaybackInfo (was null-able).
    • ToroPlayerHelper#initialize(PlaybackInfo) now has non-null PlaybackInfo (was null-able).
  • PlaybackInfo:

    • NEW: PlaybackInfo has been updated with VolumeInfo as a field.
    • NEW: Add PlaybackInfo#SCRAP object, which is a default, trivial static instance of PlaybackInfo. This instance should be used only to mark a player as un-initialized.
  • Container:

    • NEW: Add Container#getLatestPlaybackInfos() as a utility method so that client can get current playback info of all possible players at any time.
    • NEW: Add Container$Initializer interface. This interface, when set, will request client to initialize the PlaybackInfo for a ToroPlayer by its order, via Initializer#initPlaybackInfo(int). Default implementation return a trivial PlaybackInfo.
  • ExoPlayer extension:

    • Playable$EventListeners now extends a HashSet instead of ArrayList, to guarantee the uniqueness of listener to be added by its hash value.
  • Add RemoveIn annotation so that user of Toro would know when a deprecated item will be removed.

  • Some internal methods are changed to final, other improvements and also deprecated class(es) are removed.

3.4.2 (2018/04/11)

Toro 3.4.2 and above will be developed by Android Studio 3.1.0+, and maybe kotlin as well.

  • Development

    • Migrate the repo to Android Studio 3.1.1.
    • Remove gradle.properties-sample and some internal change so contributor can start forking and contributing more easily.
    • Toro is now distributed to SNAPSHOT channel as well for early builds. This enables user to try latest updates with ease. Detail can be found on README.
  • toro-core

    • Add a mechanism to support the case Container is used in CoordinatorLayout with other Views, using Behavior. Detail can be found on README.
    • Add ToroUtil#wrapParamBehavior() to help shorten the setup of new Behavior above.
    • Add VolumeInfo for a tailored volume setup. It holds the 'mute' status as well as the actual volume value when the playback is unmuted.
    • Add ToroPlayer$OnVolumeChangeListener that listens to the change of internal VolumeInfo. Instance of this interface is setup by ToroPlayerHelper and its variants.
    • Container will no longer start a delayed playback if the scroll is not idled.
  • toro-exoplayer

    • Config now accepts an array of DrmSessionManagers instead of a single DrmSessionManager. This is an experiment.
    • Add Playable#setParameters() and Playable#getParameters to match ExoPlayer behaviour.
    • Add ToroExoPlayer which extends SimpleExoPlayer and provides the ability to work with VolumeInfo.
    • Playable and default implementations are updated to work with VolumeInfo.
  • toro-mopub

    • Add custom UI components: PlayerView and ToroControlView that combines ExoPlayer r2.4.4 implementation with some fixes from ExoPlayer 2.7.0.
    • Add Playable#setParameters() and Playable#getParameters to match ExoPlayer behaviour.
    • Add ToroExoPlayer which extends SimpleExoPlayer and provides the ability to work with VolumeInfo.
    • Playable and default implementations are updated to work with VolumeInfo.
    • Demo app is updated using new UI components as well as VolumeInfo.
  • Others: minor performance improvement update.

  • Detail implementation and suggested usage can be found on demo applications.

3.4.1 (2018/03/06)

  • Fix a critical bug in 3.4.0, which cause the NPE when initializing the playables.
  • toro-exoplayer: Some methods of ExoCreator and MediaSourceBuilder now requires the Uri extension as option, to deal with the case that actual Url doesn't end with file extension. Client should pass expected media type so that ExoPlayer can build suitable MediaSource instances. As a result, ExoPlayerViewHelper adds addition constructor to support optional media type extension.

[Important notice, 2018/03/05] Due to some internal bugs, 3.4.0 has been pulled down from Jcenter. Please wait for 3.4.1 with the bug fixes. At the mean time, please stay at 3.3.0 or 3.4.0-A4. Sorry for the inconvenience.

3.4.0 (2018/03/04)

3.4.0 is the biggest release since 3.0.0. In short, many issues are fixed, many internal improvement and many new ways to start your new playback. This changes also focus on ExoPlayer so that using ExoPlayer with Toro is easier than ever before.

  • toro-core

    • Add PlayerDispatcher: this interface intercepts the call to ToroPlayer#play(), and tells the library 'how long should this call be delayed'. It is useful when client need some delay before the playback starts. PlayerDispatcher works with PlayerManager and can be setup using Container#setPlayerDispatcher(PlayerDispatcher). Defaul PlayerDispatcher dispatch the call immediately.
    • Improve PlayerSelector: the ToroPlayer list in parameter of PlayerSelector#select() is always sorted, while the order is unclear to the caller. This release adds the annotation Sorted telling the caller if a list is sorted by which order (either ASCENDING or DESCENDING).
    • ToroPlayer: ToroPlayer#onSettled(Container) is deprecated and will be removed in next major release (3.5.0).
    • ToroPlayerHelper: instance of Container is no longer required when constructing an instance of this class. This brings flexibility and usability to the subclass of this helper. Also, it removes the concern about sharing instance of this helper across different Containers. Along with this update, initialize(PlaybackInfo) is deprecated and replaced by initialize(Container container, PlaybackInfo). Sub class still need to override initialize(PlaybackInfo) for backward compatibility, but it is recommended to use/call the new one in practice.
    • ToroPlayerHelper: default behavior when the ToroPlayer state changes to play or pause is changed. When ToroPlayer's state is playing, the player View will keep the screen on, and when the state is pause, player View will not keep the screen on.
    • This release adds setVolume(float) and getVolume to the helper as well. Sub classes must provide a volume control for this change.
    • DrmMedia adds method multiSession() that returns a boolean telling if the Drm playback should supports multi sessions or not. This adapts the change from ExoPlayer, but not depend on it.
  • toro-exoplayer (Toro Extension for ExoPlayer 2)

    • Has been vastly rewritten. Building new SimpleExoPlayer instance is now easier and more flexible than before. And the instance will be cached for re-use, which shows significant performance improvement. Client now has the simpler and safer way to integrate ExoPlayer into ToroPlayer, and also the ability to use ExoPlayer separately to ToroPlayer's API with the same flexibility.
    • This release comes with some new helper classes, including ToroExo, ExoCreator, Config, Playable, ExoPlayable, MediaSourceBuilder.
    • ExoCreator: this is the main character, playing the roles that create new SimpleExoPlayer instances, MediaSource instances and also Playable instance.
    • Config: this class defines the necessary setup for a SimpleExoPlayer as well as MediaSource. Its instance can be built using Builder, which gives client the ease of use and the flexibility to reuse the Config instance (By calling Config#newBuilder(), client can simply clone the Config and update it with different options). Also, it is recommended to have global instance of Config for each client, and if it requires different configs, the number of config should be kept as small as possible.
    • Playable: similar to ToroPlayer in that it defines core playback control such as play/pause and volume update. But this interface is built for ExoPlayer components, and deeply integrates into its API. Instance of this interface can be used either in a subclass of ToroPlayerHelper to support a ToroPlayer, or individually as a single playback controller. Playable is designed to be resuable, even across configuration change, so that client can keept the playback smoothly in those changes.
    • ExoPlayable: an implementation of Playable where client can extend it for customization with flexibility.
    • MediaSourceBuilder: a single interface tells client how should a MediaSource should be created, and ask for the implementation. Providing the Config by an instance of this interface is enough for the rest of your app.
    • ToroExo: the manager for this new update. It hides the complexity of implementations of ExoCreator or Playable, gives client necessary but powerful entry points to request for those instances. Also, initiating this class is just as simple as calling ToroExo.with(context) you may see else where. ToroExo.with(Context), ToroExo#requestPlayer(ExoCreator), ToroExo#releasePlayer(ExoCreator, SimpleExoCreator), ToroExo#getCreator(Config), ToroExo#getDefaultCreator() are only methods you need to remember.
    • ExoPlayerViewHelper is renamed from ExoPlayerHelper and also a rewritten version of it. It is the combination between ToroPlayerHelper and ExoPlayable, brings the best of this release to user of toro.
    • SimpleExoPlayerViewHelper is deprecated, client should use ExoPlayerViewHelper instead. This class will be removed from next major release (3.5.0).
  • toro-mopub

    • The changes for this extension is almost the same with the toro-exoplayer, while its responsibility is to keep the compatibility with ExoPlayer r2.4.4, which is non-trivial.
    • The addition interfaces are the same, but their signature are slightly different. Client is recommended to check out the source to take a look. But to use them, it is just as simple as calling the same methods from ToroExo with the same set of options as in toro-exoplayer.
    • PlayerView is added. It is a clone of SimpleExoPlayerView where there are some addition improvement brought from ExoPlayer 2.7.0.
    • ToroControlView is added, with a custom UI where user can also change the Volume. This options is not available in official ExoPlayer Widgets, which is the reason why I create this View.
    • The old MediaSourceBuilder is renamed to MediaSourceCreator and also be created in favor to the new setup for ExoPlayer.
    • The new MediaSourceBuild class is added to work with new building system for ExoPlayer.
    • Helpers for ToroPlayer are now: PlayerViewHelper for new custom PlayerView and ExoPlayerViewHelper for SimpleExoPlayerView.
  • Demo

    • Add demo-exoplayer that contains simple Activities to show how to use the new ToroExo with all other new classes, either with Container or as single Media player.
    • Add demo-mopub to show how to use toro-mopub extension effectively.
  • Others

    • toro-exoplayer now uses ExoPlayer 2.7.0 as dependency.
    • app the demo app is also updated with latest ExoPlayer version and latest improvement from toro-exoplayer.

3.4.0-alpha3 (2018/02/24)

  • toro-core

    • Add PlayerDispatcher to provide more flexible playback. In detail, it can delay the call to ToroPlayer#play() where the delay time is configurable by client. Default behavior is no delay.
  • toro-exoplayer

    • Now compile with ExoPlayer version 2.7.0. There are breaking changes in that library, so clients of Toro are expected to migrate them. The migration is trivial.
  • All demo apps are now compile with ExoPlayer version 2.7.0.

3.4.0-alpha2 (2018/02/19)

This release improve alpha 1, regarding usability of Playable instance, minor (but important) implementation improvement that in turns improve client UX and performance, and many other tiny tuning.

  • Changes for Playable:

    • attacheView(SimpleExoPlayerView) and detachView() are replaced by one method setPlayerView(SimpleExoPlayerView), makes more sense.
    • Playable.EventListener now extends MetadataOutput as well. Client should update the implementation.
    • PlayableImpl has been improve so that: MediaSource will be prepared only after client calls play() for the first time. This is to prevent Device to download the media even if the playback is not requested.
  • Changes for ToroExo:

    • ToroExo#cleanUp() is added so that client can aggressively/actively cleanup all currently cached SimpleExoPlayer instance. This is useful when the Application is running out of memory. Note that only instances those are staying in the Pool are released, ones are in used is not affected by this, which is expected.
    • ToroExo#requestPlayer(ExoCreator) is added, so that client can effectively request for SimpleExoPlayer instance. Instead of calling ExoCreator#createPlayer() in alpha1, which will not mind the cache, this method will only create new instance of there is no cache in the Pool.
    • ToroExo#releasePlayer(ExoCreator, SimpleExoPlayer) is added, on-par with the method above. Client can use this method to release an SimpleExoPlayer instance back to the Pool (which must be mapped to the ExoCreator).
  • Other changes:

    • DefaultExoCreator is changed to public so that client can extend it for custom usage.
    • ExoPlayerViewHelper constructor signature's items order has been change.
  • Update to demo-exoplayer: PlayableDemoActivity.kt has been updated with the logic to reuse Playable instance across config change. This shows how to keep the playback smooth across config change (eg: Window size change, Orientation change, etc). This update take the use of onRetainCustomNonConfigurationInstance which may or may not good practice, so User to this library should consider this as a "Proof of Concept" kind of thing, and get the concept of how it can work. I actively work on this to figure out a good way for production level stability.

    • How is the behavior: the Activity can start normally in either orientation. If it starts in landscape mode or multi windows mode whose horizontal edge is longer than vertical edge, it will be a single full-screen player. If it starts in portrait mode or multi windows mode whose horizontal edge is shorter than vertical edge, it will be a list of content and the Player view stays on top of the LinearLayout (inside a NestedScrollView, etc).
    • When you change the config by either change the orientation or enter multi windows mode, the Activity do necessary cleanup, save the Playable instance via onRetainCustomNonConfigurationInstance and so on. When the Activity is recreated, retrieve the Playable and update its Player view to the new one. This way, the Audio playback is kept smoothly while Video playback is disturbed by the Config change only.
    • Note that this implementation involves 'Switching the Surface' for SimpleExoPlayer, which in turns the MediaCodec and so on. This work is known to be troublesome in low-spec/low-level Devices. It should work best on API 23+. So making it widely usable in production is a long way ahead. Just you have been warned.

3.4.0-alpha1 (2018/02/12)

This pre-release bring overall improvement to ExoPlayer extension. The interfaces are kept unchanged (or a little), but the underneath implementation is re-written. Detail is as below:

  • New interface ExoCreator that helps to create a new SimpleExoPlayer instance as well as to build a MediaSource from existing Uri. Implementing of this interface should always return a creation result, not from cache. Toro take care of the caching mechanism for SimpleExoPlayer instances and will call this interface if need. DefaultExoCreator is the default implementation for this interface.

  • Playable interface defines playback behavior. Implementation of this interface must guarantee to survive config change. ExoCreator will also create a Playable, using default implementation (See ExoCreator#createPlayable(Uri)).

  • Config class defines the configuration for a ExoCreator. One config should be kept statically for one Application. One App can have one or more Configs. ToroExo holds a default config that fits most of the cases so you don't have to create anything by default. Build up a new Config by using its Config$Builder class, or by using Config#newBuilder() to create a Builder from current Config.

  • ToroExo is the global manager of this update. It helps manager the cache for SimpleExoPlayer, ExoCreator, etc. Obtaining its (singleton) by calling ToroExo.with(context) and from there, Client has the access into its functionality.

  • Some old event listeners (interfaces) are replaced with Playable$EventListener. Client need to update them.

  • SimpleExoPlayerViewHelper is kept but its internal implementation has changed using the new mechanism. This class's existence is to maintain backward compatibility of current Clients using older library. In fact, Client still need to migrate to use the new EventListener, but the change should be a little. Changing to use ExoPlayerViewHelper is recommended.

  • New demo app dedicated for ExoPlayer extension is added: demo-exoplayer. Currently, there are 3 demos:

    • BasicListActivity shows normal usage of Toro with new implementation of ExoPlayerViewHelper. Written in Kotlin.
    • CreatorDemoActivity shows non-Toro use case, where Client use ExoCreator API to build SimpleExoPlayer and MediaSource. Written in Java.
    • PlayableDemoActivity shows non-Toro use case, where Client use ExoCreator API to build Playable. Written in Kotlin.

3.3.0 (2018/01/01)

This release contains breaking changes, minor migration may be required.

API Updates

  • BREAKING CHANGE: Remove ExoPlayer API from Core. This is to remove the dependant of Toro from ExoPlayer. Some libraries may use older version of ExoPlayer. Current implementation of ExoPlayer is released as separated extension for Toro, User should add the following entry to gradle:
implementation "im.ene.toro3:toro-ext-exoplayer:${toroVersion}" // same version as Toro
  • BREAKING CHANGE: ExoPlayer extension is released as separated library (see above). This extension will always use latest version of ExoPlayer. For this time's release, it is 2.6.0. User can refer to its implementation to support different version which doesn't binary compatible (for example r2.4.4).

Internal Updates

  • Various implementation improvement.

Demo App Updates

  • YouTube demo application is improved, full-screen player is added. Forkers of this library are required to provide their own application Id for YouTube demo app (see gradle.properties-sample) for the key.

3.2.0 (2017/11/23)

This release will make scrolling with many Videos smoother. Sorry for making you wait!

API Updates

  • BREAKING CHANGE: ToroPlayer#onContainerScrollStateChange(Container, int) has been removed, replaced by ToroPlayer#onSettled(Container).
  • BREAKING CHANGE: ToroPlayer#onCompleted(Container, ToroPlayer) has been removed, replaced by ToroPlayer#onCompleted().
  • BREAKING CHANGE: ToroLayoutManager has been removed. Internal implement now doesn't depend on first and last ViewHolder indicator.

Internal Updates

  • ToroUtil#visibleAreaOffset() implementation now doesn't require ViewParent to be a Container anymore.
  • Common#allowsToPlay() implementation improved.
  • Container and PlayerManager internal implementation has been significantly improved.

Demo App Updates

  • Minor coding improvement for Youtube demo.

3.1.1 (2017/10/06)

Internal Updates

  • Inline documentation is improved. (I was bad at documenting things, sorry).
  • ExoPlayer version is updated to 2.5.3.

Demo App Updates

  • Add demo with single player activity, where User can click to a Video to start a dedicated Player for it. Read source code for more information.

3.1.0 (2017/09/05)

API Updates

  • Inline documentation is improved.
  • ExoPlayer version is updated to 2.5.1 (This version is not binary compatible with 2.4.x).

Bug fixes

  • Fix a bug where Container keeps playing while Device Screen is turned off.

3.0.0 (2017/08/02)

API Updates

  • Add ToroPlayer#onContainerScrollStateChange to allow ToroPlayer to hook into Container scroll state change event.
  • Add ToroPlayerHelper#onContainerScrollStateChange which does nothing, so that sub class can used to provide helpful support for ToroPlayer.
  • ExoPlayer version is updated to 2.4.4

Demo app update

  • Add ViewPagers in ViewPager demo, which demonstrates how to handle more complicated use case where user have ViewPager inside Fragment which in turns is inside another ViewPager. (The problem is when a ViewPager is shown to the user).

  • Add app-youtube module to show the use of toro with Youtube video, using Android Youtube Player API. To be able to build this module, user must provide a youtube api key to gradle.properties (see gradle.properties-sample for the key, replace the dummy key to the actual key, rename this file to gradle.properties as usual and build).

Other update

  • toro now requires Android Studio 3.0 to develop.

3.0.0 Beta 1 (2017/07/07)

七夕だ、make a wish

API Updates

  • VideoView support has been removed. An example of using it is added in Sample app.

  • ToroUtil#visibleAreaOffset(View, View) has become ToroUtil#visibleAreaOffset(ToroPlayer, ViewParent). This allows a more accurate calculation and less error prone usage.

  • PlayerStateManager is deprecated and removed. The reason is its implementation is not obvious to user as well as the common way to use this is to have a HashMap of PlaybackInfo. So I include the implementation into Container itself.

  • CacheManager has been added, replace the PlayerStateManager. This interface only asks for the Key of a ToroPlayer's cache, which will be easier to implement and understand. This interface also comes with default implementation, but it is highly recommended that users have their own implementation using the real dataset.

  • PlayerSelector#select(View container, List<ToroPlayer> items) has become PlayerSelector#select(Container container, List<ToroPlayer> items) to ensure the type-safety of implementations.

  • Cancellable interface has been removed.

  • ToroPlayerHelper#cancel() is now ToroPlayerHelper#release() as Cancellable is removed.

  • [Bug Fix] ToroPlayerHelper now has default ToroPlayer.EventListener to correctly handle the playback's complete event.

  • ExoPlayerHelper and other classes those supports ExoPlayer library are now re-located into exoplayer package.

  • MediaSourceBuilder class is added, provides the easy way to build up ExoPlayer's MediaSource. Along with this, ExoPlayerHelper#prepare() methods will now accept MediaSourceBuilder and optional BandwidthMeter instead of current Uri or MediaSource. This change will increases the flexibility for the users of this library.

  • Add DrmMediaProvider interface by which ExoPlayerHelper can know if application is using a Drm media or not.

  • [Bug Fix] ExoPlayerHelper will now correctly update resume position: it will not use Player's data if the Player is in IDLE state.

  • All method that add listener/callback will require a non-null parameter.

  • [Bug Fix] SimpleExoPlayerViewHelper will now initialize at most once.

  • Container's internal implementation updates:  - No longer need null check for PlayerManager instance.  - Container#getActivePlayers() is removed, there is Container#filterBy(Filter) which is more powerful. Filter is a new interface that will check a ToroPlayer for some condition (Same as Java 8Predicate interface).  - It will throw an NPE at runtime if ToroPlayer#getPlayerView() returns null.  - [Bug Fix] setAdapter and swapAdapter are now correctly using result from super class for the old Adapter before setting up the new one.  - Container#savePlaybackInfo(int, PlaybackInfo), Container#getPlaybackInfo(int), Container#getSavedPlayerOrders() are newly added to replace the old PlayerStateManager. Those methods above are public.  - CacheManager setter/getter are added.

  • (Internal API) Common#allowsToPlay(View videoView, Container parent) is now less complicated and (hopefully) more comprehensive and correct.

Sample app updates

  • Sample app is totally revised, in which each feature is implemented in its own package, without sharing any component with other, even the layout file. This allow users to be able to use it as-it, as well as confidently modify the code without harming other feature's implementation.

  • There are 7 + 1 demos at the moment, carefully implemented:  

    • Custom LayoutManager: this is the entry point of Sample app, also shows the use of Toro using custom LayoutManager.  Clicking to OPEN DEMOS will reveal more demonstrations as below. This demo also showcases the use of LoopingMediaSource using a custom ToroPlayerHelper and LoopingMediaSourceBuilder.  

    • Basic: using Toro with least effort. This shows how simple it is to get start with Toro. Also this sample does not support playback info save/restore.

    • Facebook Timeline: this demo uses Toro to mimic the behaviour of Facebook's timeline, with click to open playlist, rotate to open current Video in full-screen. It also surpass the default behavior by correctly handling the config changes and supporting Multi-Windows mode. This demo also showcases a custom use of ToroPlayer.EventListener to allow the playlist to automatically scroll to next player after completing the playback.  

    • Nested Container: this demo shows how to use a Container inside other Container. The real use case of this is the suggested Video list for a specific Video (like Youtube).  

    • Complicated Grid (Complex Grid): this demo shows how to use Toro to control number of simultaneous players at one time. Again this is a power consumed feature and not recommended.    - Flexible Grid: this is the same as Complex Grid demo above, with the addition of drag/drop feature. This represents the Toro's ability of supporting data changes.  

    • Legacy: this demo shows how to use Toro with Android's default VideoView. In this package, there is a custom VideoView adding the ability to listen to play/pause event which is required in some cases.  

    • ViewPager: last but not least, this demo shows how to use Toro with many Containers that are hosted by a ViewPager (each page is a Fragment having a Container). The Activity lauched by clicking OPEN DEMOS is where the ViewPager is. So instead of clicking to button in first page to open a specific demo, swiping over the page will also reveal those demos. Note that: some of the demos will not appear in ViewPager demo due to technicle issue.

3.0.0 alpha 2 (2017/06/30)

API Updates

  • Drop support to VideoView (via ToroVideoView and LegacyVideoViewHelper). User can find a demo of using VideoView in demo app, legacy package.

  • Move PlayerSelector from im.ene.toro.widget to im.ene.toro.

  • Method name change: ToroPlayerHelper#updatePlaybackInfo becomes ToroPlayerHelper#getLatestPlaybackInfo.

  • All initialize method now requires a Nullable PlaybackInfo (was Nonnull).

Sample app updates

  • Add demo for VideoView.

Others

  • Minor coding improvement and documentation improvement.

3.0.0 alpha 1 (2017/06/24)

Toro 3.0 is a completely rewritten version of Toro. I borrow just a few helper from 2.x.

To integrate Toro in your App, just replace the RecyclerView to Container in place of Video list.

<im.ene.toro.widget.Container
  android:id="@+id/recycler_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:max_player_number="1"
/>

Next: implement ToroPlayer to the ViewHolder that will be a Media player.

public class SimpleExoPlayerViewHolder extends RecyclerView.ViewHolder implements ToroPlayer {

  static final int LAYOUT_RES = R.layout.vh_exoplayer_basic;

  @Nullable SimpleExoPlayerViewHelper helper;
  @Nullable private Uri mediaUri;

  @BindView(R.id.player) SimpleExoPlayerView playerView;

  SimpleExoPlayerViewHolder(View itemView) {
    super(itemView);
    ButterKnife.bind(this, itemView);
  }

  @Override
  public void bind(@NonNull RecyclerView.Adapter adapter, Uri item, List<Object> payloads) {
    if (item != null) {
      mediaUri = item;
    }
  }

  @NonNull @Override public View getPlayerView() {
    return playerView;
  }

  @NonNull @Override public PlaybackInfo getCurrentPlaybackInfo() {
    PlaybackInfo state = new PlaybackInfo();
    if (helper != null) state = helper.getLatestPlaybackInfo();
    return state;
  }

  @Override
  public void initialize(@NonNull Container container, @Nullable PlaybackInfo playbackInfo) {
    if (helper == null) {
      helper = new SimpleExoPlayerViewHelper(container, this, mediaUri);
      helper.setEventListener(eventListener);
    }
    helper.initialize(playbackInfo);
  }

  @Override public void release() {
    if (helper != null) {
      try {
        helper.cancel();
      } catch (Exception e) {
        e.printStackTrace();
      }
      helper = null;
    }
  }

  @Override public void play() {
    if (helper != null) helper.play();
  }

  @Override public void pause() {
    if (helper != null) helper.pause();
  }

  @Override public boolean isPlaying() {
    return helper != null && helper.isPlaying();
  }

  @Override public boolean wantsToPlay() {
    ViewParent parent = itemView.getParent();
    float offset = 0;
    if (parent != null && parent instanceof View) {
      offset = ToroUtil.visibleAreaOffset(playerView, (View) parent);
    }
    return offset >= 0.85;
  }

  @Override public int getPlayerOrder() {
    return getAdapterPosition();
  }
}

You are ready to have Toro 3.0 support. More advance usage are being updated.