8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Xperia端末でVideoViewで動画再生時に緑色に点滅する現象を回避する

Last updated at Posted at 2017-12-13

はじめに

2017/12/11 ~ 12 にかけて調査した結果のログです。

拙作のTwitterクライアントのユーザーから「動画再生中にしばらくすると緑色に点滅する現象が発生するので何とかして欲しい」という報告がたびたび来ていました。

報告のあった端末をまとめると、いずれも Android 5.0~6.0 のXperia端末で、比較的長い動画の再生中に発生するという共通点がありました。

2017-12-13_11h08_35.png

手元の SOL25 でも再現できたため、調査を開始。具体的には 30 秒ほどの動画を再生し、2ループ目で発生していました。

アプリ側の調査

VideoView 周辺のレイアウトを変えてみるなど

2017-12-13_11h11_58.png

VideoView は ConstraintLayout -> FrameLayout -> VideoView の中にあり、下にSeekBarや疑似ツールバーなど色々と配置されているのでこれらが原因で発生する可能性を疑い、RelativeLayout に変えてみたり、RelativeLayout -> VideoView だけのシンプルなレイアウトにしてみたりしたけど解決せず。

次にVideoViewを扱うコード側の問題を疑い、新規に VideoView だけ配置したActivity だけを持つアプリを作ってみたけどやはり現象は消えず。

ループ処理周辺を疑う

2ループ目で発生するのでその周辺のコードを調べてみました。

        videoView.setOnCompletionListener {
            // ループ再生フラグの確認
            if (TPConfig.isMoviePlayerRepeating(applicationContext)) {

                // ループ再生
                videoView.seekTo(0)
                videoView.start()

                mPaused = false
            } else {
...
            }
        }

他にも SeekBar タップ時にもたまに発生するので、どうやら videoView.seekTo を使うと発生するっぽいことが見えてきました。

WorkAround として

"VideoView flickering" "VideoView flash" などのキーワードで検索しまくった(数時間かけてわりとしらみつぶしに色んなコードを試した)のですが全く手がかりを得られず。

VideoView のソースを見ると SurfaceView + MediaPlayer なのでそれらと OpenGL 周辺の調査も必要かなぁと諦めかけ。

どこかの Stack Overflow で VideoView.resume()re-buffering などと説明していたのを参考に、試しに seekTo(0) の前に resume() を呼んでみると本現象はひとまず発生しなくなった。とはいえ resume() すると少し再生が止まるので綺麗なループ再生が出来なくなり、全端末で採用するのはキツイ WorkAround でした。

現象の特定と設定値の条件

Screen Record すると改善される?

Android Studio の logcat タブの Screen Record 機能を使って本現象を録画してみようとしたところ、録画を開始してすぐに点滅現象が収まることが分かりました。

すると某先輩から有力な手がかりが。

試してみると確かに Xperia 端末の設定画面にある「画面設定」⇒「高画質モード」を「X-Reality for mobile」から「オフ」にすると本現象は全く発生しなくなることが分かりました。Xperiaめ!

噂では YouTube アプリでも同様の現象が起きるようなのでまた少し諦めかけ。

Xperia端末の高画質モードの設定値を探す

"how to get x-reality mode" のようなキーワードで探しまくるも端末の設定から変更するものばかり。

X-Reality モードはソニー自慢の BRAVIA エンジン(かな?)を Xperia 端末に導入したもので、動画再生中に適用されるものらしい。最新のXperia端末には最新の X-Reality が入っていて、それを少し古い端末でも使えるようにする APK が非公式に配布されていたりしていました。

"xperia x-reality mode java" で検索してたどり着いた [Tut][MoD][Xperia devices] Bravia/Supervivid/x-reality もその解説記事でしたが、その一部に設定画面を変更する部分がありました。

2017-12-13_11h42_42.png

というわけで、「高画質モード」の設定画面が "com.sonymobile.imageenhancer" で提供されていることが分かりました。

APK を持ってくる

手元の SOL25 の実機から "com.sonymobile.imageenhancer" を持ってきます。

Android 実機から apk を探して取得 - clock-up-blog を参考に、

$ adb shell pm list packages -f
...
package:/system/app/ImageEnhancer/ImageEnhancer.apk=com.sonymobile.imageenhancer
...

で該当パッケージのAPKフルパスを取得できるので、

$ adb pull /system/app/ImageEnhancer/ImageEnhancer.apk

でAPKを取得。

ごにょごにょする

あとは APK をごにょごにょして調べます。

SystemProperties から取得する

直接は呼び出せないのでリフレクションなどで該当する値を取得したところ、確かに高画質モードの設定画面で変更した値を取得できました。

というわけで、

先ほどの VideoView.resume()VideoView.seekTo() の前に実行するという WorkAround を「Android 6.0以下 で persist.service.xrfm.mode がOn(0以外)の場合にのみ実行する」ことで最小限の端末で WorkAround を実行できるようになりました。

おしまい

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?