10000 Add video rotation and video size change event callbacks. · PushoN/flutter-webrtc@c75069f · GitHub
[go: up one dir, main page]

Skip to content

Commit c75069f

Browse files
committed
Add video rotation and video size change event callbacks.
1 parent 5825f9b commit c75069f

File tree

8 files changed

+248
-148
lines changed

8 files changed

+248
-148
lines changed

example/lib/main.dart

Lines changed: 99 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,69 @@ class MyApp extends StatefulWidget {
1919
class _MyAppState extends State<MyApp> {
2020
MediaStream _localStream;
2121
RTCPeerConnection _peerConnection;
22-
final _localVideoView = new RTCVideoViewController();
23-
final _remoteVideoView = new RTCVideoViewController();
24-
final _width = 200.0;
25-
final _height = 200.0;
22+
var _width = 240.0;
23+
var _height = 180.0;
24+
var _rotation = 0;
25+
final _localVideoRenderer = new RTCVideoRenderer();
26+
final _remoteVideoRenderer = new RTCVideoRenderer();
2627

2728
@override
2829
initState() {
2930
super.initState();
3031
initPlatformState();
32+
_localVideoRenderer.onVideoRotationChange = _onVideoRotationChange;
3133
}
3234

33-
_onAddStream(MediaStream stream)
35+
_onVideoRotationChange(int textureId, int rotation)
3436
{
35-
_remoteVideoView.srcObject = stream;
37+
setState((){
38+
_rotation = rotation;
39+
});
3640
}
3741

38-
_onRemoveStream(MediaStream stream){
39-
_remoteVideoView.srcObject = null;
42+
_onVideoSizeChange(int textureId, double width, double height){
43+
44+
}
45+
46+
_onSignalingState(RTCSignalingState state) {
47+
print(state);
48+
}
49+
50+
_onIceGatheringState(RTCIceGatheringState state) {
51+
print(state);
52+
}
53+
54+
_onIceConnectionState(RTCIceConnectionState state) {
55+
print(state);
56+
}
57+
58+
_onAddStream(MediaStream stream) {
59+
print('addStream: ' + stream.id);
60+
_remoteVideoRenderer.srcObject = stream;
4061
}
4162

42-
_onCandidate(RTCIceCandidate candidate){
63+
_onRemoveStream(MediaStream stream) {
64+
_remoteVideoRenderer.srcObject = null;
65+
}
66+
67+
_onCandidate(RTCIceCandidate candidate) {
68+
print('onCandidate: ' + candidate.candidate);
4369
_peerConnection.addCandidate(candidate);
4470
}
4571

72+
_onRenegotiationNeeded() {
73+
print('RenegotiationNeeded');
74+
}
75+
4676
// Platform messages are asynchronous, so we initialize in an async method.
4777
initPlatformState() async {
4878
final Map<String, dynamic> mediaConstraints = {
4979
"audio": true,
5080
"video": {
5181
"mandatory": {
52-
"minWidth": '640', // Provide your own width, height and frame rate here
53-
"minHeight": '360',
82+
"minWidth":
83+
'640', // Provide your own width, height and frame rate here
84+
"minHeight": '480',
5485
"minFrameRate": '30',
5586
},
5687
"facingMode": "user",
@@ -62,52 +93,59 @@ class _MyAppState extends State<MyApp> {
6293
"audio": true,
6394
"video": true,
6495
};*/
65-
Map<String, dynamic> configuration = {
96+
Map<String, dynamic> configuration = {
6697
"iceServers": [
67-
{ "url" : "stun:stun.l.google.com:19302"},
68-
]
69-
};
98+
{"url": "stun:stun.l.google.com:19302"},
99+
]
100+
};
70101

71-
final Map<String, dynamic> OFFER_SDP_CONSTRAINTS = {
102+
final Map<String, dynamic> OFFER_SDP_CONSTRAINTS = {
72103
"mandatory": {
73104
"OfferToReceiveAudio": true,
74105
"OfferToReceiveVideo": true,
75106
},
76107
"optional": [],
77108
};
78109

79-
final Map<String, dynamic> LOOPBACK_CONSTRAINTS = {
110+
final Map<String, dynamic> LOOPBACK_CONSTRAINTS = {
80111
"mandatory": {},
81112
"optional": [
82-
{"DtlsSrtpKeyAgreement": false },
113+
{"DtlsSrtpKeyAgreement": false},
83114
],
84115
};
85116

86117
// Platform messages may fail, so we use a try/catch PlatformException.
87118
try {
88119
_localStream = await getUserMedia(mediaConstraints);
89-
await _localVideoView.initialize(_width, _height);
90-
await _remoteVideoView.initialize(_width, _height);
120+
await _localVideoRenderer.initialize(_width, _height);
121+
await _remoteVideoRenderer.initialize(_width, _height);
122+
_localVideoRenderer.srcObject = _localStream;
123+
124+
_peerConnection =
125+
await createPeerConnection(configuration, LOOPBACK_CONSTRAINTS);
91126

92-
_peerConnection = await createPeerConnection(configuration, LOOPBACK_CONSTRAINTS);
127+
_peerConnection.onSignalingState = _onSignalingState;
128+
_peerConnection.onIceGatheringState = _onIceGatheringState;
129+
_peerConnection.onIceConnectionState = _onIceConnectionState;
93130
_peerConnection.onAddStream = _onAddStream;
94131
_peerConnection.onRemoveStream = _onRemoveStream;
95132
_peerConnection.onIceCandidate = _onCandidate;
133+
_peerConnection.onRenegotiationNeeded = _onRenegotiationNeeded;
134+
96135
_peerConnection.addStream(_localStream);
97-
RTCSessionDescrption description = await _peerConnection.createOffer(OFFER_SDP_CONSTRAINTS);
136+
RTCSessionDescrption description =
137+
await _peerConnection.createOffer(OFFER_SDP_CONSTRAINTS);
138+
print(description.sdp);
98139
_peerConnection.setLocalDescription(description);
99140
//change for loopback.
100141
description.type = 'answer';
101142
_peerConnection.setRemoteDescription(description);
102-
} catch(e) {
103-
//'Failed to get platform version.';
143+
} catch (e) {
144+
//'Failed to get platform version.';
104145
}
105-
if (!mounted)
106-
return;
146+
if (!mounted) return;
107147

108-
setState(() {
109-
_localVideoView.srcObject = _localStream;
110-
});
148+
setState(() {});
111149
}
112150

113151
@override
@@ -117,28 +155,38 @@ class _MyAppState extends State<MyApp> {
117155
appBar: new AppBar(
118156
title: new Text('Flutter-WebRTC example'),
119157
),
120-
body: new Center( child: new Column(
121-
crossAxisAlignment: CrossAxisAlignment.start,
122-
children: [
123-
new Text('WebRTC loopback demo.'),
124-
new Container(
125-
width: _width,
126-
height: _height,
127-
child: _localVideoView.isInitialized
128-
? new Texture(textureId: _localVideoView.renderId)
129-
: null,
130-
),
131-
new Text('Local video'),
132-
new Container(
133-
width: _width,
134-
height: _height,
135-
child: _remoteVideoView.isInitialized
136-
? new Texture(textureId: _remoteVideoView.renderId)
137-
: null,
138-
),
139-
new Text('Remote video'),
140-
])
141-
),
158+
body: new Center(
159+
child: new Column(
160+
crossAxisAlignment: CrossAxisAlignment.start,
161+
children: [
162+
new Text('Loopback demo.'),
163+
new Transform(
164+
child: new Container(
165+
width: _width,
166+
height: _height,
167+
child: _remoteVideoRenderer.isInitialized
168+
? new Texture(textureId: _remoteVideoRenderer.renderId)
169+
: null,
170+
),
171+
alignment: FractionalOffset.center, // set transform origin
172+
transform: new Matrix4.identity()
173+
.. F987 rotateZ(_rotation * 3.1415927 / 180),
174+
),
175+
new Text('Local video'),
176+
new Transform(
177+
child: new Container(
178+
width: _width,
179+
height: _height,
180+
child: _remoteVideoRenderer.isInitialized
181+
? new Texture(textureId: _remoteVideoRenderer.renderId)
182+
: null,
183+
),
184+
alignment: FractionalOffset.center, // set transform origin
185+
transform: new Matrix4.identity()
186+
..rotateZ(90 * 3.1415927 / 180),
187+
),
188+
new Text('Remote video'),
189+
])),
142190
),
143191
);
144192
}

ios/Classes/FlutterRTCVideoViewManager.h

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,27 @@
11
#import "FlutterWebRTCPlugin.h"
22

3-
#import <WebRTC/RTCEAGLVideoView.h>
3+
#import <WebRTC/RTCVideoRenderer.h>
44
#import <WebRTC/RTCMediaStream.h>
55
#import <WebRTC/RTCVideoFrame.h>
66
#import <WebRTC/RTCVideoTrack.h>
77

8-
/**
9-
* In the fashion of
10-
* https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth
11-
* and https://www.w3.org/TR/html5/rendering.html#video-object-fit, resembles
12-
* the CSS style {@code object-fit}.
13-
*/
14-
typedef NS_ENUM(NSInteger, RTCVideoViewObjectFit) {
15-
/**
16-
* The contain value defined by https://www.w3.org/TR/css3-images/#object-fit:
17-
*
18-
* The replaced content is sized to maintain its aspect ratio while fitting
19-
* within the element's content box.
20-
*/
21-
RTCVideoViewObjectFitContain,
22-
/**
23-
* The cover value defined by https://www.w3.org/TR/css3-images/#object-fit:
24-
*
25-
* The replaced content is sized to maintain its aspect ratio while filling
26-
* the element's entire content box.
27-
*/
28-
RTCVideoViewObjectFitCover
29-
};
8+
9+
typedef void(^onChangeVideoSizeCallback)(int width, int height);
10+
typedef void(^onRotationChangeCallback)(int rotation);
3011

3112
/**
3213
* Implements an equivalent of {@code HTMLVideoElement} i.e. Web's video
3314
* element.
3415
*/
35-
@interface RTCVideoView : NSObject <FlutterTexture, RTCVideoRenderer>
36-
37-
/**
38-
* The indicator which determines whether this {@code RTCVideoView} is to mirror
39-
* the video specified by {@link #videoTrack} during its rendering. Typically,
40-
* applications choose to mirror the front/user-facing camera.
41-
*/
42-
@property (nonatomic) BOOL mirror;
43-
44-
/**
45-
* In the fashion of
46-
* https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth
47-
* and https://www.w3.org/TR/html5/rendering.html#video-object-fit, resembles
48-
* the CSS style {@code object-fit}.
49-
*/
50-
@property (nonatomic) RTCVideoViewObjectFit objectFit;
16+
@interface RTCVideoView : NSObject <FlutterTexture, RTCVideoRenderer, FlutterStreamHandler>
5117

5218
/**
5319
* The {@link RTCVideoTrack}, if any, which this instance renders.
5420
*/
5521
@property (nonatomic, strong) RTCVideoTrack *videoTrack;
56-
@property (copy, nonatomic) void(^onNewFrame)(void);
22+
@property (nonatomic) int64_t textureId;
23+
@property (nonatomic, weak) id<FlutterTextureRegistry> registry;
24+
@property (nonatomic, strong) FlutterEventSink eventSink;
5725

5826
- (instancetype)initWithSize:(CGSize)renderSize;
5927

@@ -64,7 +32,9 @@ typedef NS_ENUM(NSInteger, RTCVideoViewObjectFit) {
6432

6533
@interface FlutterWebRTCPlugin (RTCVideoViewManager)
6634

67-
- (RTCVideoView *)createWithSize:(CGSize)size onNewFrame:(void(^)(void))onNewFrame;
35+
- (RTCVideoView *)createWithSize:(CGSize)size
36+
withTextureRegistry:(id<FlutterTextureRegistry>)registry
37+
messenger:(NSObject<FlutterBinaryMessenger>*)messenger;
6838

6939
-(void)setStreamId:(NSString*)streamId view:(RTCVideoView*)view;
7040

0 commit comments

Comments
 (0)
0