MostafaDadkhah / Flutter_onvif

Available in pub.dv
https://pub.dev/packages/onvif
MIT License
9 stars 7 forks source link

Error in stream onvif camera, 400 bad request error for GetDeviceInformation request #1

Closed anayajoshi closed 3 years ago

anayajoshi commented 4 years ago

E/flutter (24192): Receiver: "Http status error [400]" E/flutter (24192): Tried calling: source E/flutter (24192): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5) E/flutter (24192): #1 httpPost (package:flutter_app_onvifcamera/onvif/Repository/SendData.dart:27:22) E/flutter (24192): E/flutter (24192): #2 ONVIF._updateCapabilities (package:flutter_app_onvifcamera/onvif/ONVIF.dart:42:33) E/flutter (24192): #3 ONVIF.getCameraUri (package:flutter_app_onvifcamera/onvif/ONVIF.dart:56:22) E/flutter (24192): #4 _MyHomePageState.connect (package:flutter_app_onvifcamera/main.dart:112:30) E/flutter (24192): #5 _MyHomePageState.build... (package:flutter_app_onvifcamera/main.dart:92:23) E/flutter (24192): #6 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19) E/flutter (24192): #7 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:1098:38) E/flutter (24192): #8 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24) E/flutter (24192): #9 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11) E/flutter (24192): #10 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5) E/flutter (24192): #11 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:256:7) E/flutter (24192): #12 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:158:27) E/flutter (24192): #13 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:224:20) E/flutter (24192): #14 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22) E/flutter (24192): #15 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)

MostafaDadkhah commented 4 years ago

show me your code.

anayajoshi commented 4 years ago

I am using the same example you have given, compiled in android studio and run on android tab. I am using CPPlus camera which is ONVIF supported and I have checked it with native android application. It works ok with native android application. Then why its giving error with flutter application? Please guide.

anayajoshi commented 4 years ago

I am using the same example you have given, compiled in android studio and run on android tab. I am using CPPlus camera which is ONVIF supported and I have checked it with native android application. It works ok with native android application. Then why its giving error with flutter application? Please guide.

I am waiting for reply. Please guide.

MostafaDadkhah commented 4 years ago

show me your code.

anayajoshi commented 4 years ago

I am sending here two main files code. I am using the same code as you have given. Which file code you want to see?

main.dart file code as below:

import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_app_onvifcamera/onvif/Model/OnvifDevice.dart'; import 'package:flutter_app_onvifcamera/onvif/ONVIF.dart'; import 'VideoPlayer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);

final String title;

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

class _MyHomePageState extends State { List devices = []; StreamController<List> streamDevicesController = StreamController() ; ListusernameController=[]; ListpasswordController=[]; ListusernameFocus=[]; ListpasswordFocus=[]; ONVIF onvif = ONVIF(); @override void initState() {

onvif.getDevices((device){
  devices.add(device);
  streamDevicesController.add(devices);
  usernameController.add(TextEditingController());
  passwordController.add(TextEditingController());
  usernameFocus.add(FocusNode());
  passwordFocus.add(FocusNode());
});

super.initState();

} @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: StreamBuilder( stream: streamDevicesController.stream, builder: (BuildContext context , AsyncSnapshot<List>snapshot){ List data = (snapshot.data)??[]; return GridView.builder(gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 4.0, mainAxisSpacing: 4.0), itemCount: data.length, itemBuilder: (BuildContext context , int index){ return Card(child: Column(children: [ TextField( controller: usernameController[index], decoration: InputDecoration( hintText: "Username" ), focusNode: usernameFocus[index], textInputAction: TextInputAction.next, onSubmitted: (value){ _fieldFocusChange(context, usernameFocus[index], passwordFocus[index]); }, ), TextField( controller: passwordController[index], decoration: InputDecoration( hintText: "Password" ), focusNode: passwordFocus[index], textInputAction: TextInputAction.done, onSubmitted: (value){ connect(data[index] , usernameController[index].text , passwordController[index].text ); }, ), RaisedButton(child: Text("connect"), onPressed: (){ connect(data[index] , usernameController[index].text , passwordController[index].text ); },), SizedBox(height: 20,), Text(showIP(data[index])),

            ],), );
          });
    },
  ),
);

} void _fieldFocusChange(BuildContext context, FocusNode currentFocus,FocusNode nextFocus) { currentFocus.unfocus(); FocusScope.of(context).requestFocus(nextFocus); } String showIP(OnvifDevice device){ return device.xAddr.split('/')[2]; } void connect(OnvifDevice onvifDev , String username , String password)async{

String uri = await onvif.getCameraUri(onvifDev, username, password);
Navigator.push(context,
    MaterialPageRoute(
      builder: (context) => VideoPlayer(uri , username , password),));

} }

ONVIF.dart file code as below: library onvif; import 'dart:async'; import 'package:flutter_app_onvifcamera/onvif/Model/OnvifDevice.dart'; import 'BLOC.dart'; import 'Model/NetworkProtocol.dart'; import 'Model/Probe.dart'; import 'Model/ProbeMatch.dart'; import 'Repository/ParseData.dart'; import 'Repository/ProcessResponse.dart'; import 'Repository/SendData.dart'; import 'Repository/Utils.dart'; import 'Repository/buildMessages.dart';

class ONVIF{

ONVIF(); void getDevices(Function(OnvifDevice)onDone) async { List probeMatchList = []; Probe.messageID = 'uuid:'+ getUUID(); String message = buildProbeMessage(Probe.messageID ); sendMulticast("239.255.255.250",3702, message , (messageRecivied){ probeData.add(messageRecivied);}); Probe.netHandle.listen((inComingProbe){ if(inComingProbe != ""){ readResponse(inComingProbe); probeMatchData.probeMatches.listen((inComingProbeMatch) async{ if(inComingProbeMatch.xAddrs[0] !=""){ removeFreeProbeMatches(probeMatchList); if(!inlist(probeMatchList,inComingProbeMatch)){ probeMatchList.add(inComingProbeMatch); OnvifDevice onvifDev = await processMatch(inComingProbeMatch); onDone(onvifDev); } } }); } }); }

Future _updateCapabilities(String username , String password , OnvifDevice device )async{ String message = buildGetDeviceInformationMessage(device , username , password); String information = await httpPost(device.xAddr, message); Map<String, String> deviceInformation = parseGetDeviceInformation(information); device.serial = deviceInformation['serialNumber']; device.model = deviceInformation['model']; message = buildGetCapabilitiesMessage(device, username, password, "All"); information = await httpPost(device.xAddr, message); Map<String,String> capablities = parseGetCapabilities(information); device.xAddr = capablities['XAddr']; device.eventsXAddr = capablities['Events']; device.mediaXAddr = capablities['Media']; return device; }

FuturegetCameraUri(OnvifDevice device , String username , String password)async{ device = await _updateCapabilities(username, password, device); List networkProtocols = await _getNetworkProtocols(device , username , password); for(NetworkProtocol networkProtocol in networkProtocols){ if (networkProtocol.name == "HTTPS"){ networkProtocol.enabled = true; networkProtocol.port = 443; } } String message = buildGetProfilesMessages(device, username, password); String profiles = await httpPost(device.mediaXAddr, message); List profileList = parseGetProfiles(profiles); String targetProfileToken = profileList.last; Map<String , String> streamSetup = <String,String>{}; streamSetup["stream"] = "RTP-Unicast"; streamSetup["protocol"] ="HTTP"; streamSetup["tunnel"] = null; message = buildGetStreamUriMessage(device , username , password, streamSetup, targetProfileToken); String result = await httpPost(device.mediaXAddr, message); return parseGetMediaUri(result);

}

Future<List<NetworkProtocol>> _getNetworkProtocols(OnvifDevice device , String username , String password)async{
  String message = buildGetNetworkProtocolsMessage(device, username , password);
  final info = await httpPost(device.xAddr, message);
  return parseGetNetworkProtocols(info);
}

}

MostafaDadkhah commented 4 years ago

These are the files I wrote. I do not understand what you mean. Now you ran my example file and after giving the username and password to VLC, have a problem? Explain the problem clearly.

anayajoshi commented 4 years ago

These are the files I wrote. I do not understand what you mean. Now you ran my example file and after giving the username and password to VLC, have a problem? Explain the problem clearly.

Yes, I ran your example, it discovers my CPPLUS camera, after gave username and password and click on connect button, it does not stream camera and giving 400 bad request error, as as given in issue description.

Please give the solution.

MostafaDadkhah commented 4 years ago

I am using the same example you have given, compiled in android studio and run on android tab. I am using CPPlus camera which is ONVIF supported and I have checked it with native android application. It works ok with native android application. Then why its giving error with flutter application? Please guide.

What was the Android app you checked? Please provide me with the link

anayajoshi commented 4 years ago

I am using the same example you have given, compiled in android studio and run on android tab. I am using CPPlus camera which is ONVIF supported and I have checked it with native android application. It works ok with native android application. Then why its giving error with flutter application? Please guide.

What was the Android app you checked? Please provide me with the link

Onvifer app at play store

IoTServ commented 3 years ago

I use example the same problem @MostafaDadkhah

IoTServ commented 3 years ago

oh.I found why the error occurred,some device may not work,such as Network Video Recorder(NVR) may can discovered with onvif protocol,but it can't get stream uri with the Lib,and produce this error and exit the program. @MostafaDadkhah @anayajoshi

IoTServ commented 3 years ago

When I skip the NVR device then I got the uri

IoTServ commented 3 years ago
import  'package:onvif/Model/OnvifDevice.dart';
import  'package:onvif/onvif.dart';
void main(List<String> arguments) {
  List<OnvifDevice> devices = [];
  ONVIF onvif = ONVIF();
  onvif.getDevices((device) async {
    print(device.xAddr);
    //skip the NVR by ip,
    // NVR ip is 192.168.123.200
    //ip Camera ip is 192.168.123.211
    if (device.xAddr.contains("123.200")) {
      return;
    }
    String uri = await onvif.getCameraUri(device, "admin", "");
    print(uri);
    devices.add(device);
  });
}

output:

http://192.168.123.200/onvif/device_service
http://192.168.123.211:8899/onvif/device_service
rtsp://192.168.123.211:554/user=admin_password=tlJwpbo6_channel=1_stream=1.sdp?real_stream

@MostafaDadkhah @anayajoshi

IoTServ commented 3 years ago

then I use the url, all OK

截屏2021-01-23 下午10 48 59
IoTServ commented 3 years ago

And some other problem on Android platform,I will make a PR to fix the example Android may need and

android:usesCleartextTraffic="true"

for insecure Traffic(http)

IoTServ commented 3 years ago

2