如何通过Miracast从Android应用投射网址?

时间:2019-02-06 04:32:01

标签: android casting youtube chromecast miracast

我尝试通过miracast将YouTube视频从我的Android应用投射到chromecast或智能电视。 但我只能投射https://media.w3.org/2010/05/sintel/trailer.mp4

这样的视频的源网址

如何投放带有youtube或vimeo网址视频的网页?

我知道YouTube应用程序可以在不进行chromecast的情况下将视频投射到一些智能电视上,并且看起来像YouTube TV页面。例如这里https://www.youtube.com/watch?v=x5ImUYDjocY

我尝试使用Presentation API在其中设置WebView:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
class CastPresentation constructor(outerContext: Context?, display: Display?) : Presentation(outerContext, display) {

  override fun onCreate(savedInstanceState: Bundle?) {
    val wv = WebView(context)
    wv.settings.javaScriptEnabled = true
    wv.webChromeClient = WebChromeClient()
    wv.loadUrl("https://www.youtube.com/watch?v=DxGLn_Cu5l0")
    setContentView(wv)
    super.onCreate(savedInstanceState)
  }
}

但这不会影响。我不了解如何使用它。

这是我的用法:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
class CastDelegate constructor(private val activity: AppCompatActivity) {

  private var mediaRouter: MediaRouter? = null
  private var mediaRouteSelector: MediaRouteSelector? = null

  // Variables to hold the currently selected route and its playback client
  private var route: MediaRouter.RouteInfo? = null
  private var remotePlaybackClient: RemotePlaybackClient? = null
  private var presentation: Presentation? = null

  // Define the Callback object and its methods, save the object in a class variable
  private val mediaRouterCallback = object : MediaRouter.Callback() {

    override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) {
      Timber.d("CastDelegate --> onRouteSelected: route=$route")
      if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
        // Stop local playback (if necessary)
        // ...

        // Save the new route
        this@CastDelegate.route = route

        // Attach a new playback client
        remotePlaybackClient = RemotePlaybackClient(activity, this@CastDelegate.route)

        // Start remote playback (if necessary)
        // ...
        updatePresentation()
        val uri = Uri.parse("https://media.w3.org/2010/05/sintel/trailer.mp4")
        remotePlaybackClient?.play(uri, null, null, 0, null, object: RemotePlaybackClient.ItemActionCallback() {
          override fun onResult(data: Bundle?, sessionId: String?, sessionStatus: MediaSessionStatus?, itemId: String?, itemStatus: MediaItemStatus?) {
            super.onResult(data, sessionId, sessionStatus, itemId, itemStatus)
          }
        })
      }
    }

    override fun onRouteUnselected(router: MediaRouter, route: MediaRouter.RouteInfo, reason: Int) {
      Timber.d("CastDelegate --> onRouteUnselected: route=$route")
      if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {

        // Changed route: tear down previous client
        this@CastDelegate.route?.also {
          remotePlaybackClient?.release()
          remotePlaybackClient = null
        }

        // Save the new route
        this@CastDelegate.route = route
        updatePresentation()

        when (reason) {
          MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> {
            // Resume local playback (if necessary)
            // ...
          }
        }
      }
    }

    override fun onRoutePresentationDisplayChanged(router: MediaRouter?, route: MediaRouter.RouteInfo?) {
      updatePresentation()
    }
  }

  fun onCreate() {
    // Get the media router service.
    mediaRouter = MediaRouter.getInstance(activity)

    // Create a route selector for the type of routes your app supports.
    mediaRouteSelector = MediaRouteSelector.Builder()
        // These are the framework-supported intents
        .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
        .build()

//    val selectedRoute = mediaRouter?.selectedRoute ?: return
//    val presentationDisplay = selectedRoute.presentationDisplay ?: return
//    presentation = CastPresentation(activity, presentationDisplay)
//    presentation?.show()
  }

  fun onStart() {
    mediaRouteSelector?.also { selector ->
      mediaRouter?.addCallback(selector, mediaRouterCallback,
          MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY)
    }
    updatePresentation()
  }

  fun onStop() {
    mediaRouter?.removeCallback(mediaRouterCallback)
    presentation?.dismiss()
    presentation = null
  }

  fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {

    // Attach the MediaRouteSelector to the menu item
    val mediaRouteMenuItem = menu?.findItem(R.id.media_route_menu_item)
    val mediaRouteActionProvider = MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider

    // Attach the MediaRouteSelector that you built in onCreate()
    mediaRouteSelector?.also(mediaRouteActionProvider::setRouteSelector)

  }

  private fun updatePresentation() {
    // Get the current route and its presentation display.
    val selectedRoute = mediaRouter?.selectedRoute
    val presentationDisplay = selectedRoute?.presentationDisplay

    // Dismiss the current presentation if the display has changed.
    if (presentation?.display != presentationDisplay) {
      Timber.d("CastDelegate --> Dismissing presentation because the current route no longer " + "has a presentation display.")
      presentation?.dismiss()
      presentation = null
    }

    // Show a new presentation if needed.
    if (presentation == null && presentationDisplay != null) {
      Timber.d("CastDelegate --> Showing presentation on display: $presentationDisplay")
      presentation = CastPresentation(activity, presentationDisplay)
      try {
        presentation?.show()
      } catch (ex: WindowManager.InvalidDisplayException) {
        Timber.d("CastDelegate --> Couldn't show presentation!  Display was removed in the meantime.", ex)
        presentation = null
      }

    }
  }
}

因此,现在播放来自{p>的视频https://media.w3.org/2010/05/sintel/trailer.mp4

  

remotePlaybackClient?.play(...)

0 个答案:

没有答案