I have a page on which I am playing videos from both the links, these are:

  • Youtube URLs
  • Normal Video URLs like Vimeo etc

I have used this famous flutter package that is, video_player, and also used a very useful package which wraps the video_player with all the inbuilt controls, which is, chewie 0.9.10

Now the above one is capable of running the videos which are normal, and not from Youtube. For Youtube videos, there are packages available, these are: youtube_player_flutter and youtube_player.

But the Challenge here is, to find a workaround which plays both of the videos that is from NORMAL VIDEO URL and YOUTUBE URL without having any problem. I am searching for a way out, and found nothing till then. I hope I find some useful answers here, so that I can make use of it in my flutter application. Thanks


Solution 1: Felipe Fernandes

video_player or chewie can only network(with streaming url), assets or file videos. So first we need a way to indentify if the video URL is from youtube. Then we can use the youtube_explode_dart to obtain the youtube video stream url, so the player can reproduce.

Below is a code snippet from one of my projects:

String convertUrlToId(String url, {bool trimWhitespaces = true}) {
  assert(url?.isNotEmpty ?? false, 'Url cannot be empty');
  String _url;
  if (!url.contains('http') && (url.length == 11)) return url;
  if (trimWhitespaces) {
    _url = url.trim();
  } else {
    _url = url;
  }

  for (final exp in [
    RegExp(r'^https:\/\/(?:www\.|m\.)?youtube\.com\/watch\?v=([_\-a-zA-Z0-9]{11}).*$'),
    RegExp(
        r'^https:\/\/(?:www\.|m\.)?youtube(?:-nocookie)?\.com\/embed\/([_\-a-zA-Z0-9]{11}).*$'),
    RegExp(r'^https:\/\/youtu\.be\/([_\-a-zA-Z0-9]{11}).*$')
  ]) {
    final Match match = exp.firstMatch(_url);
    if (match != null && match.groupCount >= 1) return match.group(1);
  }

  return null;
}
Future<String> _extractVideoUrl() async {
  if (%%IS_VIDEO_FROM_YOUTUBE%%) {
    final extractor = YoutubeExplode();
    final videoId = convertUrlToId(widget.videoUrl);
    final streamManifest = await extractor.videos.streamsClient.getManifest(videoId);
    final streamInfo = streamManifest.muxed.withHighestBitrate();
    extractor.close();
    return streamInfo.url.toString();
  }
  return null;
}

And then, finally.

_videoPlayerController = VideoPlayerController.network(%%URL_EXTRACTED%%)..initialize();