flutter: отображение видео из базы данных (MYSQL)

#php #flutter #dart

#php #трепетание #dart

Вопрос:

у меня есть видео в (БАЗА ДАННЫХ MYSQL), и мне нужно отобразить его в flutter На самом деле я исследовал эту тему и не нашел полезного объяснения, так как я правильно загрузил видео в базу данных, и мне нужно отобразить его с помощью flutter, и я перепробовал много методов, но это не сработало итак, я проверяю код для серверной части, и он работает нормально, он возвращает данные в формате json без каких-либо проблем, но проблема в интерфейсе, я не знаю, как просмотреть его с помощью flutter, мне нужно отобразить его как youtube, проблема, которая мне кажется, такая, как показано на рисунке

введите описание изображения здесь

я распечатал данные, поступающие из базы данных, и преобразовал их в данные json, и ничего плохого, как показано на рисунке

введите описание изображения здесь

это код для серверной части

  <?php
require_once("config.php");
require_once("class/video.php");
require_once("home.php");
require_once("class/VideoPlayer.php");


if (!isset($_GET["id"])) {
    echo "No url passed into page";
    exit();
}

$video = new Video($con, $_GET["id"], $userLoggedInObj);


$getId          = $video->getId();
$getUploadedBy  = $video->getUploadedBy();
$getTitle       = $video->getTitle();
$getDescription = $video->getDescription();
$getPrivacy     = $video->getPrivacy();
$getFilePath    = $video->getFilePath();
$getCategory    = $video->getCategory();
$getViews       = $video->getViews();
$getDuration    = $video->getDuration();
$incrementViews = $video->incrementViews();

echo json_encode(array('id' => $getId, 'uploadedBy' => $getUploadedBy, 'title' => $getTitle, 'description' => $getDescription, 'views' => $getViews, 'duration' => $getDuration, 'filePath' => $getFilePath));


?>
 

это код для класса VideoItem

  class VideoItem {
  final id;
  final filePath;
  final uploadedBy;
  final title;
  final description;
  final views;
  final duration;

  VideoItem(
      {this.id,
      this.filePath,
      this.uploadedBy,
      this.title,
      this.description,
      this.views,
      this.duration});

  factory VideoItem.fromJson(Map<String, dynamic> jsonData) {
    return VideoItem(
      id: jsonData['id'],
      filePath: jsonData['filePath'],
      uploadedBy: jsonData['uploadedBy'],
      title: jsonData['title'],
      description: jsonData['description'],
      views: jsonData['views'],
      duration: jsonData['duration'],
    );
  }
}
 

это код для класса CustomListView

     import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
import 'package:youtubeclone/pages/videodetails/videoitem.dart';

class CustomListView extends StatefulWidget {
  final List<VideoItem> videoListView;

  CustomListView({this.videoListView});

  @override
  _CustomListViewState createState() => _CustomListViewState();
}

class _CustomListViewState extends State<CustomListView> {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: widget.videoListView.length,
      itemBuilder: (context, int currentIndex) {
        return createViewItem(widget.videoListView[currentIndex], context);
      },
    );
  }

  Widget createViewItem(VideoItem videoItem, BuildContext context) {
    final List<YoutubePlayerController> _controllers =
        [videoItem.id, videoItem.filePath]
            .map<YoutubePlayerController>(
              (videoId) => YoutubePlayerController(
                initialVideoId: videoId,
                flags: YoutubePlayerFlags(
                  autoPlay: false,
                ),
              ),
            )
            .toList();
    return Padding(
      padding: EdgeInsets.all(10),
      child: Card(
        elevation: 1.6,
        child: Padding(
          padding: EdgeInsets.all(5),
          child: YoutubePlayer(
            key: ObjectKey(videoItem.id),
            controller: _controllers[0],
            actionsPadding: EdgeInsets.only(left: 16.0),
            bottomActions: [
              CurrentPosition(),
              SizedBox(width: 10.0),
              ProgressBar(isExpanded: true),
              SizedBox(width: 10.0),
              RemainingDuration(),
              FullScreenButton(),
            ],
          ),
        ),
      ),
    );
  }
}
 

это класс для наблюдения

  import 'package:flutter/material.dart';
import 'package:youtubeclone/pages/componets/appbarallproject.dart';
import 'package:youtubeclone/pages/componets/mydrawer.dart';
import 'package:http/http.dart' show get;
import 'package:youtubeclone/pages/videodetails/customlistview.dart';
import 'dart:convert';
import 'videodetails/videoitem.dart';

class Watch extends StatefulWidget {
  @override
  _WatchState createState() => _WatchState();
}

class _WatchState extends State<Watch> {
  GlobalKey<ScaffoldState> _drawerKey = GlobalKey();
  VideoItem videoItem;
  Future<List<VideoItem>> downloadJson() async {
    //var data = {"id": videoItem.id, "filePath": videoItem.filePath};
    final url = "http://10.0.2.2/videoTube/watch.php";
    final response = await get(url);

    if (response.statusCode == 200) {
      List videoListItem = json.decode(response.body);
      return videoListItem
          .map((videoListItem) => new VideoItem.fromJson(videoListItem))
          .toList();
    } else {
      throw Exception(
          "we were not able to successfully download the json data");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        key: _drawerKey,
        drawer: MyDrawer(),
        appBar: AppBarAllProject(drawerKey: _drawerKey),
        body: Center(
          child: FutureBuilder<List<VideoItem>>(
            future: downloadJson(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                List<VideoItem> video = snapshot.data;
                return CustomListView(
                  videoListView: video,
                );
              } else if (snapshot.hasData) {
                return Text('${snapshot.error}');
              }
              //return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}
 

Ответ №1:

Внутри ваших FutureBuilder операторов if else не охватывает все возможные результаты. FutureBuilder всегда должен возвращать виджет. С помощью этого кода вы сможете увидеть сообщение об ошибке и исправить свой код в будущем.

 if (snapshot.hasData) {
  List<VideoItem> video = snapshot.data;
  return CustomListView(
    videoListView: video,
  );
} else if (snapshot.hasError) {
  return Text('${snapshot.error}');
} else {
  return Text('Unknown condition');
}
 

Комментарии:

1. я получил эту ошибку ((((NoSuchMethodError: идентификатор получателя был вызван в null. Получатель: null Пытался вызвать: id))))

2. @MuhammedJack Спасибо тебе. Я скоро отредактирую свой ответ!

Ответ №2:

В вашем PHP-коде вы отображаете только один объект, но ожидаете список объектов в Flutter. Вы должны настроить свой код Flutter так, чтобы он принимал один объект. Вот так:

 if (response.statusCode == 200) {
  Map videoListItem = json.decode(response.body);
  return videoListItem = VideoItem.fromJson(videoListItem);
} 
 

Комментарии:

1. выдает мне эту ошибку (((Значение типа ‘VideoItem’ не может быть присвоено переменной типа ‘Map<динамический, динамический>’. Попробуйте изменить тип переменной или привести правый тип к ‘Map<dynamic, dynamic>’))) поэтому я привел его к (((возвращает videoListItem = VideoItem.FromJSON(videoListItem) как Map;))

2. и выдает мне другую ошибку (((Значение типа ‘Map<dynamic, dynamic>’ не может быть возвращено из метода ‘downloadJson’, потому что он имеет возвращаемый тип ‘Future<List<VideoItem>>’)))

3. @MuhammedJack Прав. Там будет несколько мест, которые вам придется исправить. Вместо списка VideoListItem у вас есть один элемент списка. Вам придется соответствующим образом обновить свой код.