2

私はアンドロイド UPnP/DLNA アプリに取り組んでいます。メディア サーバーからレンダラーにファイルをストリーミングできるコントロール ポイントが動作しています。再生中にファイルを一時停止/再生して停止することはできますが、シークバーをコントロール ポイントに統合して再生中のファイルの進行状況を表示し、シークバーを操作できるようにする方法がわかりません。Cling Java ライブラリを使用してアプリを作成しています。誰かが私を助けることができる例を持っていれば、本当に感謝しています.

ありがとう

SubscriptionCallback の例を実装して、LastChange に登録しようとしました

SubscriptionCallback callback = new SubscriptionCallback(service, 600) { // Timeout in seconds

                 public void established(GENASubscription sub) {
                     System.out.println("Established: " + sub.getSubscriptionId());


                 }
                 @Override
                 public void failed(GENASubscription sub, UpnpResponse response, Exception ex) {
                     System.err.println(
                         createDefaultFailureMessage(response, ex)
                     );
                 }
                 @Override
                 public void ended(GENASubscription sub, CancelReason reason, UpnpResponse response) {
                     // Reason should be null, or it didn't end regularly
                 }

                 public void eventReceived(GENASubscription sub) {
                     System.out.println("Event: " + sub.getCurrentSequence().getValue());


                               try {
                                   lastChange = new LastChange(
                                           new AVTransportLastChangeParser(),
                                           sub.getCurrentValues().get("LastChange").toString()
                                   );


                               } catch (Exception ex) {
                                   log.warning("Error parsing LastChange event content: " + ex);
                                   return;
                               }

                     Map<String, StateVariableValue> values = sub.getCurrentValues();
                     StateVariableValue status = values.get("Status");
                     System.out.println("Status is: " + status.toString());
                 }

                 public void eventsMissed(GENASubscription sub, int numberOfMissedEvents) {
                     System.out.println("Missed events: " + numberOfMissedEvents);
                 }
                @Override
                protected void failed(GENASubscription arg0,
                        UpnpResponse arg1, Exception arg2, String arg3) {

                }
            };

            upnpService.getControlPoint().execute(callback);

次に、現在再生中のトラックの長さを取得しようとします。

System.out.println("Duration: "+lastChange.getEventedValue(0, AVTransportVariable.CurrentTrackDuration.class).getValue());

しかし、これは NullPointerException を返します。

何か案は???????

** * ** * ** * ** *更新* ** * ** * ** * *

Seek() を実装しようとしましたが、成功していません。

シークバーとリスナーがありますが、シークバーを新しい位置にドラッグすると失敗し続けます。

seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() 
{
        @Override
        public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) 
        {
            Log.i("SEEKTIME", "time:" + arg1);
            upnpService.getControlPoint().execute(new Seek(service, SeekMode.REL_TIME, arg0.toString())
            {
                @Override
                public void success(ActionInvocation invocation)
                {
                    //super.success(invocation);
                    Log.i("SEEKSUCCESS", "success seek");
                }
                @Override
                public void failure(ActionInvocation arg0, UpnpResponse arg1, String arg2)
                {
                    Log.i("SEEKFAIL", "fail seek");
                }
            });
        }

これが失敗する理由についての提案

4

1 に答える 1

6

この種の情報については、レンダラーをポーリングする必要があります ( AVTransport 仕様の章 2.3.1を参照)。仕様では毎秒ポーリングが推奨されていますが、実際のハードウェア レンダラーを簡単に妨害することができます (DLNA は、設計の重要な部分というよりも、依然としてファッショナブルな苦痛です)。私たちの確立された慣行は、GetPositionInfo()2 ~ 3 秒ごとにリクエストを送信し、返さRelativeTimePositionれた値をローカルで実行されているタイマーの調整としてのみ扱うことです。シークバーのサイズ設定には、現在のメディアの全長も必要です。にサブスクライブすると、レンダラーが自動的に教えてくれるのが理想的ですAVTransport.LastChange。特にClingについては知りませんが、簡単に見てみると有望な例が に示されていcontrolpoint.SubscriptionCallbackます。残念ながら、実際のデバイスでは、LastChange多くの場合、何も教えてくれません。値がまったくないか、一定の不活性値があります。GetMediaInfo()したがって、再度ポーリングして値を使用する必要がありMediaDurationます。

インタラクションに関してSeek()は、あなたの友人であり、理想的にはUnit = REL_TIMETarget= 希望する時間オフセットのパラメーターを使用します。実際のレンダラーは、シークのこの単位 (モード) をサポートしていない可能性があることに注意してください。おそらく、TRACK_NR のみをサポートしている可能性があります。この場合、シークバーは本質的に読み取り専用です。A_ARG_TYPE_SeekModeここでも、Cling は特定のレンダラーに許可されている値を通知できるはずです。

于 2012-07-22T21:06:17.313 に答える