├── .gitignore ├── Assets ├── Deque.meta ├── Deque │ ├── Deque.cs │ ├── Deque.cs.meta │ ├── Utility.cs │ └── Utility.cs.meta ├── Materials.meta ├── Materials │ ├── LocalVideoMat.mat │ ├── LocalVideoMat.mat.meta │ ├── RemoteVideoMat.mat │ ├── RemoteVideoMat.mat.meta │ ├── YUV2RGBShader.shader │ └── YUV2RGBShader.shader.meta ├── Plugins.meta ├── Plugins │ ├── Android.meta │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── AndroidManifest.xml.meta │ │ ├── libs.meta │ │ ├── libs │ │ │ ├── armeabi-v7a.meta │ │ │ └── armeabi-v7a │ │ │ │ ├── libjingle_peerconnection_so.so │ │ │ │ └── libjingle_peerconnection_so.so.meta │ │ ├── libwebrtc_unity.jar │ │ ├── libwebrtc_unity.jar.meta │ │ ├── mainTemplate.gradle_ │ │ └── mainTemplate.gradle_.meta │ ├── Shaders.meta │ └── Shaders │ │ ├── SampleMaterial.mat │ │ ├── SampleMaterial.mat.meta │ │ ├── SampleShader1.shader │ │ ├── SampleShader1.shader.meta │ │ ├── google.png │ │ └── google.png.meta ├── Socket.IO.meta ├── Socket.IO │ ├── Newtonsoft.Json.dll │ ├── Newtonsoft.Json.dll.meta │ ├── SocketIoClientDotNet.dll │ ├── SocketIoClientDotNet.dll.meta │ ├── WebSocket4Net.dll │ └── WebSocket4Net.dll.meta ├── WebRTCSample.meta └── WebRTCSample │ ├── FramePacket.cs │ ├── FramePacket.cs.meta │ ├── FramePacketPool.cs │ ├── FramePacketPool.cs.meta │ ├── FrameQueue.cs │ ├── FrameQueue.cs.meta │ ├── MovieStats.cs │ ├── MovieStats.cs.meta │ ├── PeerConnectionM.cs │ ├── PeerConnectionM.cs.meta │ ├── UI.meta │ ├── UI │ ├── ConnectButton.cs │ ├── ConnectButton.cs.meta │ ├── StatusLabel.cs │ └── StatusLabel.cs.meta │ ├── WebRtcNativeCallSample.cs │ ├── WebRtcNativeCallSample.cs.meta │ ├── WebRtcSocket.cs │ ├── WebRtcSocket.cs.meta │ ├── WebRtcVideoPlayer.cs │ ├── WebRtcVideoPlayer.cs.meta │ ├── main.unity │ └── main.unity.meta ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset ├── README.md ├── UnityPackageManager └── manifest.json └── server ├── .gitignore ├── index.html ├── index.js ├── package-lock.json ├── package.json └── server.bat /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | *.pdb.meta 29 | 30 | # Unity3D Generated File On Crash Reports 31 | sysinfo.txt 32 | 33 | # Builds 34 | *.apk 35 | *.unitypackage 36 | 37 | #trash 38 | gomi 39 | -------------------------------------------------------------------------------- /Assets/Deque.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 034b64d3684800a48b717af397c12af1 3 | folderAsset: yes 4 | timeCreated: 1520177490 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Deque/Deque.cs: -------------------------------------------------------------------------------- 1 | using DequeUtility; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace System.Collections.Generic 8 | { 9 | /// 10 | /// A genetic Deque class. It can be thought of as 11 | /// a double-ended queue, hence Deque. This allows for 12 | /// an O(1) AddFront, AddBack, RemoveFront, RemoveBack. 13 | /// The Deque also has O(1) indexed lookup, as it is backed 14 | /// by a circular array. 15 | /// 16 | /// 17 | /// The type of objects to store in the deque. 18 | /// 19 | public class Deque : IList 20 | { 21 | 22 | /// 23 | /// The default capacity of the deque. 24 | /// 25 | private const int defaultCapacity = 16; 26 | 27 | /// 28 | /// The first element offset from the beginning of the data array. 29 | /// 30 | private int startOffset; 31 | 32 | /// 33 | /// The circular array holding the items. 34 | /// 35 | private T[] buffer; 36 | 37 | /// 38 | /// Creates a new instance of the Deque class with 39 | /// the default capacity. 40 | /// 41 | public Deque() : this(defaultCapacity) { } 42 | 43 | /// 44 | /// Creates a new instance of the Deque class with 45 | /// the specified capacity. 46 | /// 47 | /// The initial capacity of the Deque. 48 | public Deque(int capacity) 49 | { 50 | if (capacity < 0) 51 | { 52 | throw new ArgumentOutOfRangeException( 53 | "capacity", "capacity is less than 0."); 54 | } 55 | 56 | this.Capacity = capacity; 57 | } 58 | 59 | /// 60 | /// Create a new instance of the Deque class with the elements 61 | /// from the specified collection. 62 | /// 63 | /// The co 64 | public Deque(IEnumerable collection) 65 | : this(Utility.Count(collection)) 66 | { 67 | InsertRange(0, collection); 68 | } 69 | 70 | private int capacityClosestPowerOfTwoMinusOne; 71 | 72 | /// 73 | /// Gets or sets the total number of elements 74 | /// the internal array can hold without resizing. 75 | /// 76 | public int Capacity 77 | { 78 | get 79 | { 80 | return buffer.Length; 81 | } 82 | 83 | set 84 | { 85 | if (value < 0) 86 | { 87 | throw new ArgumentOutOfRangeException( 88 | "value", 89 | "Capacity is less than 0."); 90 | } 91 | else if (value < this.Count) 92 | { 93 | throw new InvalidOperationException( 94 | "Capacity cannot be set to a value less than Count"); 95 | } 96 | else if (null != buffer && value == buffer.Length) 97 | { 98 | return; 99 | } 100 | 101 | // Create a new array and copy the old values. 102 | int powOfTwo = Utility.ClosestPowerOfTwoGreaterThan(value); 103 | 104 | value = powOfTwo; 105 | 106 | T[] newBuffer = new T[value]; 107 | this.CopyTo(newBuffer, 0); 108 | 109 | // Set up to use the new buffer. 110 | buffer = newBuffer; 111 | startOffset = 0; 112 | this.capacityClosestPowerOfTwoMinusOne = powOfTwo - 1; 113 | } 114 | } 115 | 116 | /// 117 | /// Gets whether or not the Deque is filled to capacity. 118 | /// 119 | public bool IsFull 120 | { 121 | get { return this.Count == this.Capacity; } 122 | } 123 | 124 | /// 125 | /// Gets whether or not the Deque is empty. 126 | /// 127 | public bool IsEmpty 128 | { 129 | get { return 0 == this.Count; } 130 | } 131 | 132 | private void ensureCapacityFor(int numElements) 133 | { 134 | if (this.Count + numElements > this.Capacity) 135 | { 136 | this.Capacity = this.Count + numElements; 137 | } 138 | } 139 | 140 | private int toBufferIndex(int index) 141 | { 142 | int bufferIndex; 143 | 144 | bufferIndex = (index + this.startOffset) 145 | & this.capacityClosestPowerOfTwoMinusOne; 146 | 147 | return bufferIndex; 148 | } 149 | 150 | private void checkIndexOutOfRange(int index) 151 | { 152 | if (index >= this.Count) 153 | { 154 | throw new IndexOutOfRangeException( 155 | "The supplied index is greater than the Count"); 156 | } 157 | } 158 | 159 | private static void checkArgumentsOutOfRange( 160 | int length, 161 | int offset, 162 | int count) 163 | { 164 | if (offset < 0) 165 | { 166 | throw new ArgumentOutOfRangeException( 167 | "offset", "Invalid offset " + offset); 168 | } 169 | 170 | if (count < 0) 171 | { 172 | throw new ArgumentOutOfRangeException( 173 | "count", "Invalid count " + count); 174 | } 175 | 176 | if (length - offset < count) 177 | { 178 | throw new ArgumentException( 179 | String.Format( 180 | "Invalid offset ({0}) or count + ({1}) " 181 | + "for source length {2}", 182 | offset, count, length)); 183 | } 184 | } 185 | 186 | private int shiftStartOffset(int value) 187 | { 188 | this.startOffset = toBufferIndex(value); 189 | 190 | return this.startOffset; 191 | } 192 | 193 | private int preShiftStartOffset(int value) 194 | { 195 | int offset = this.startOffset; 196 | this.shiftStartOffset(value); 197 | return offset; 198 | } 199 | 200 | private int postShiftStartOffset(int value) 201 | { 202 | return shiftStartOffset(value); 203 | } 204 | 205 | #region IEnumerable 206 | 207 | /// 208 | /// Returns an enumerator that iterates through the Deque. 209 | /// 210 | /// 211 | /// An iterator that can be used to iterate through the Deque. 212 | /// 213 | public IEnumerator GetEnumerator() 214 | { 215 | 216 | // The below is done for performance reasons. 217 | // Rather than doing bounds checking and modulo arithmetic 218 | // that would go along with calls to Get(index), we can skip 219 | // all of that by referencing the underlying array. 220 | 221 | if (this.startOffset + this.Count > this.Capacity) 222 | { 223 | for (int i = this.startOffset; i < this.Capacity; i++) 224 | { 225 | yield return buffer[i]; 226 | } 227 | 228 | int endIndex = toBufferIndex(this.Count); 229 | for (int i = 0; i < endIndex; i++) 230 | { 231 | yield return buffer[i]; 232 | } 233 | } 234 | else 235 | { 236 | int endIndex = this.startOffset + this.Count; 237 | for (int i = this.startOffset; i < endIndex; i++) 238 | { 239 | yield return buffer[i]; 240 | } 241 | } 242 | } 243 | 244 | /// 245 | /// Returns an enumerator that iterates through the Deque. 246 | /// 247 | /// 248 | /// An iterator that can be used to iterate through the Deque. 249 | /// 250 | IEnumerator IEnumerable.GetEnumerator() 251 | { 252 | return this.GetEnumerator(); 253 | } 254 | #endregion 255 | 256 | #region ICollection 257 | /// 258 | /// Gets a value indicating whether the Deque is read-only. 259 | /// 260 | bool ICollection.IsReadOnly 261 | { 262 | get { return false; } 263 | } 264 | 265 | /// 266 | /// Gets the number of elements contained in the Deque. 267 | /// 268 | public int Count 269 | { 270 | get; 271 | private set; 272 | } 273 | 274 | private void incrementCount(int value) 275 | { 276 | this.Count = this.Count + value; 277 | } 278 | 279 | private void decrementCount(int value) 280 | { 281 | this.Count = Math.Max(this.Count - value, 0); 282 | } 283 | 284 | /// 285 | /// Adds an item to the Deque. 286 | /// 287 | /// The object to add to the Deque. 288 | public void Add(T item) 289 | { 290 | AddBack(item); 291 | } 292 | 293 | private void ClearBuffer(int logicalIndex, int length) 294 | { 295 | int offset = toBufferIndex(logicalIndex); 296 | if (offset + length > this.Capacity) 297 | { 298 | int len = this.Capacity - offset; 299 | Array.Clear(this.buffer, offset, len); 300 | 301 | len = toBufferIndex(logicalIndex + length); 302 | Array.Clear(this.buffer, 0, len); 303 | } 304 | else 305 | { 306 | Array.Clear(this.buffer, offset, length); 307 | } 308 | } 309 | 310 | /// 311 | /// Removes all items from the Deque. 312 | /// 313 | public void Clear() 314 | { 315 | if (this.Count > 0) 316 | { 317 | ClearBuffer(0, this.Count); 318 | } 319 | this.Count = 0; 320 | this.startOffset = 0; 321 | } 322 | 323 | /// 324 | /// Determines whether the Deque contains a specific value. 325 | /// 326 | /// The object to locate in the Deque. 327 | /// 328 | /// true if item is found in the Deque; otherwise, false. 329 | /// 330 | public bool Contains(T item) 331 | { 332 | return this.IndexOf(item) != -1; 333 | } 334 | 335 | /// 336 | /// Copies the elements of the Deque to a System.Array, 337 | /// starting at a particular System.Array index. 338 | /// 339 | /// 340 | /// The one-dimensional System.Array that is the destination of 341 | /// the elements copied from the Deque. The System.Array must 342 | /// have zero-based indexing. 343 | /// 344 | /// 345 | /// The zero-based index in array at which copying begins. 346 | /// 347 | /// 348 | /// array is null. 349 | /// 350 | /// 351 | /// arrayIndex is less than 0. 352 | /// 353 | /// 354 | /// The number of elements in the source Deque is greater than 355 | /// the available space from arrayIndex to the end of the 356 | /// destination array. 357 | /// 358 | public void CopyTo(T[] array, int arrayIndex) 359 | { 360 | if (null == array) 361 | { 362 | throw new ArgumentNullException("array", "Array is null"); 363 | } 364 | 365 | // Nothing to copy 366 | if (null == this.buffer) 367 | { 368 | return; 369 | } 370 | 371 | checkArgumentsOutOfRange(array.Length, arrayIndex, this.Count); 372 | 373 | if (0 != this.startOffset 374 | && this.startOffset + this.Count >= this.Capacity) 375 | { 376 | int lengthFromStart = this.Capacity - this.startOffset; 377 | int lengthFromEnd = this.Count - lengthFromStart; 378 | 379 | Array.Copy( 380 | buffer, this.startOffset, array, 0, lengthFromStart); 381 | 382 | Array.Copy( 383 | buffer, 0, array, lengthFromStart, lengthFromEnd); 384 | } 385 | else 386 | { 387 | Array.Copy( 388 | buffer, this.startOffset, array, 0, Count); 389 | } 390 | } 391 | 392 | /// 393 | /// Removes the first occurrence of a specific object from the Deque. 394 | /// 395 | /// The object to remove from the Deque. 396 | /// 397 | /// true if item was successfully removed from the Deque; 398 | /// otherwise, false. This method also returns false if item 399 | /// is not found in the original 400 | /// 401 | public bool Remove(T item) 402 | { 403 | bool result = true; 404 | int index = IndexOf(item); 405 | 406 | if (-1 == index) 407 | { 408 | result = false; 409 | } 410 | else 411 | { 412 | RemoveAt(index); 413 | } 414 | 415 | return result; 416 | } 417 | 418 | #endregion 419 | 420 | #region List 421 | 422 | /// 423 | /// Gets or sets the element at the specified index. 424 | /// 425 | /// 426 | /// The zero-based index of the element to get or set. 427 | /// 428 | /// The element at the specified index 429 | /// 430 | /// is not a valid index in this deque 431 | /// 432 | public T this[int index] 433 | { 434 | get 435 | { 436 | return this.Get(index); 437 | } 438 | 439 | set 440 | { 441 | this.Set(index, value); 442 | } 443 | } 444 | 445 | /// 446 | /// Inserts an item to the Deque at the specified index. 447 | /// 448 | /// 449 | /// The zero-based index at which item should be inserted. 450 | /// 451 | /// The object to insert into the Deque. 452 | /// 453 | /// is not a valid index in the Deque. 454 | /// 455 | public void Insert(int index, T item) 456 | { 457 | ensureCapacityFor(1); 458 | 459 | if (index == 0) 460 | { 461 | AddFront(item); 462 | return; 463 | } 464 | else if (index == Count) 465 | { 466 | AddBack(item); 467 | return; 468 | } 469 | 470 | InsertRange(index, new[] { item }); 471 | } 472 | 473 | /// 474 | /// Determines the index of a specific item in the deque. 475 | /// 476 | /// The object to locate in the deque. 477 | /// 478 | /// The index of the item if found in the deque; otherwise, -1. 479 | /// 480 | public int IndexOf(T item) 481 | { 482 | int index = 0; 483 | foreach (var myItem in this) 484 | { 485 | if (myItem.Equals(item)) 486 | { 487 | break; 488 | } 489 | ++index; 490 | } 491 | 492 | if (index == this.Count) 493 | { 494 | index = -1; 495 | } 496 | 497 | return index; 498 | } 499 | 500 | /// 501 | /// Removes the item at the specified index. 502 | /// 503 | /// 504 | /// The zero-based index of the item to remove. 505 | /// 506 | /// 507 | /// is not a valid index in the Deque. 508 | /// 509 | public void RemoveAt(int index) 510 | { 511 | if (index == 0) 512 | { 513 | RemoveFront(); 514 | return; 515 | } 516 | else if (index == Count - 1) 517 | { 518 | RemoveBack(); 519 | return; 520 | } 521 | 522 | RemoveRange(index, 1); 523 | } 524 | #endregion 525 | 526 | /// 527 | /// Adds the provided item to the front of the Deque. 528 | /// 529 | /// The item to add. 530 | public void AddFront(T item) 531 | { 532 | ensureCapacityFor(1); 533 | buffer[postShiftStartOffset(-1)] = item; 534 | incrementCount(1); 535 | } 536 | 537 | /// 538 | /// Adds the provided item to the back of the Deque. 539 | /// 540 | /// The item to add. 541 | public void AddBack(T item) 542 | { 543 | ensureCapacityFor(1); 544 | buffer[toBufferIndex(this.Count)] = item; 545 | incrementCount(1); 546 | } 547 | 548 | /// 549 | /// Removes an item from the front of the Deque and returns it. 550 | /// 551 | /// The item at the front of the Deque. 552 | public T RemoveFront() 553 | { 554 | if (this.IsEmpty) 555 | { 556 | throw new InvalidOperationException("The Deque is empty"); 557 | } 558 | 559 | T result = buffer[this.startOffset]; 560 | buffer[preShiftStartOffset(1)] = default(T); 561 | decrementCount(1); 562 | return result; 563 | } 564 | 565 | /// 566 | /// Removes an item from the back of the Deque and returns it. 567 | /// 568 | /// The item in the back of the Deque. 569 | public T RemoveBack() 570 | { 571 | if (this.IsEmpty) 572 | { 573 | throw new InvalidOperationException("The Deque is empty"); 574 | } 575 | 576 | decrementCount(1); 577 | int endIndex = toBufferIndex(this.Count); 578 | T result = buffer[endIndex]; 579 | buffer[endIndex] = default(T); 580 | 581 | return result; 582 | } 583 | 584 | /// 585 | /// Adds a collection of items to the Deque. 586 | /// 587 | /// The collection to add. 588 | public void AddRange(IEnumerable collection) 589 | { 590 | AddBackRange(collection); 591 | } 592 | 593 | /// 594 | /// Adds a collection of items to the front of the Deque. 595 | /// 596 | /// The collection to add. 597 | public void AddFrontRange(IEnumerable collection) 598 | { 599 | AddFrontRange(collection, 0, Utility.Count(collection)); 600 | } 601 | 602 | /// 603 | /// Adds count items from a collection of items 604 | /// from a specified index to the Deque. 605 | /// 606 | /// The collection to add. 607 | /// 608 | /// The index in the collection to begin adding from. 609 | /// 610 | /// 611 | /// The number of items in the collection to add. 612 | /// 613 | public void AddFrontRange( 614 | IEnumerable collection, 615 | int fromIndex, 616 | int count) 617 | { 618 | InsertRange(0, collection, fromIndex, count); 619 | } 620 | 621 | /// 622 | /// Adds a collection of items to the back of the Deque. 623 | /// 624 | /// The collection to add. 625 | public void AddBackRange(IEnumerable collection) 626 | { 627 | AddBackRange(collection, 0, Utility.Count(collection)); 628 | } 629 | 630 | /// 631 | /// Adds count items from a collection of items 632 | /// from a specified index to the back of the Deque. 633 | /// 634 | /// The collection to add. 635 | /// 636 | /// The index in the collection to begin adding from. 637 | /// 638 | /// 639 | /// The number of items in the collection to add. 640 | /// 641 | public void AddBackRange( 642 | IEnumerable collection, 643 | int fromIndex, 644 | int count) 645 | { 646 | InsertRange(this.Count, collection, fromIndex, count); 647 | } 648 | 649 | /// 650 | /// Inserts a collection of items into the Deque 651 | /// at the specified index. 652 | /// 653 | /// 654 | /// The index in the Deque to insert the collection. 655 | /// 656 | /// The collection to add. 657 | public void InsertRange(int index, IEnumerable collection) 658 | { 659 | int count = Utility.Count(collection); 660 | this.InsertRange(index, collection, 0, count); 661 | } 662 | 663 | /// 664 | /// Inserts count items from a collection of items from a specified 665 | /// index into the Deque at the specified index. 666 | /// 667 | /// 668 | /// The index in the Deque to insert the collection. 669 | /// 670 | /// The collection to add. 671 | /// 672 | /// The index in the collection to begin adding from. 673 | /// 674 | /// 675 | /// The number of items in the colleciton to add. 676 | /// 677 | public void InsertRange( 678 | int index, 679 | IEnumerable collection, 680 | int fromIndex, 681 | int count) 682 | { 683 | checkIndexOutOfRange(index - 1); 684 | 685 | if (0 == count) 686 | { 687 | return; 688 | } 689 | 690 | // Make room 691 | ensureCapacityFor(count); 692 | 693 | if (index < this.Count / 2) 694 | { 695 | // Inserting into the first half of the list 696 | 697 | if (index > 0) 698 | { 699 | // Move items down: 700 | // [0, index) -> 701 | // [Capacity - count, Capacity - count + index) 702 | int copyCount = index; 703 | int shiftIndex = this.Capacity - count; 704 | for (int j = 0; j < copyCount; j++) 705 | { 706 | buffer[toBufferIndex(shiftIndex + j)] = 707 | buffer[toBufferIndex(j)]; 708 | } 709 | } 710 | 711 | // shift the starting offset 712 | this.shiftStartOffset(-count); 713 | 714 | } 715 | else 716 | { 717 | // Inserting into the second half of the list 718 | 719 | if (index < this.Count) 720 | { 721 | // Move items up: 722 | // [index, Count) -> [index + count, count + Count) 723 | int copyCount = this.Count - index; 724 | int shiftIndex = index + count; 725 | for (int j = 0; j < copyCount; j++) 726 | { 727 | buffer[toBufferIndex(shiftIndex + j)] = 728 | buffer[toBufferIndex(index + j)]; 729 | } 730 | } 731 | } 732 | 733 | // Copy new items into place 734 | int i = index; 735 | foreach (T item in collection) 736 | { 737 | buffer[toBufferIndex(i)] = item; 738 | ++i; 739 | } 740 | 741 | // Adjust valid count 742 | incrementCount(count); 743 | } 744 | 745 | /// 746 | /// Removes a range of elements from the view. 747 | /// 748 | /// 749 | /// The index into the view at which the range begins. 750 | /// 751 | /// 752 | /// The number of elements in the range. This must be greater 753 | /// than 0 and less than or equal to . 754 | /// 755 | public void RemoveRange(int index, int count) 756 | { 757 | if (this.IsEmpty) 758 | { 759 | throw new InvalidOperationException("The Deque is empty"); 760 | } 761 | if (index > Count - count) 762 | { 763 | throw new IndexOutOfRangeException( 764 | "The supplied index is greater than the Count"); 765 | } 766 | 767 | // Clear out the underlying array 768 | ClearBuffer(index, count); 769 | 770 | if (index == 0) 771 | { 772 | // Removing from the beginning: shift the start offset 773 | this.shiftStartOffset(count); 774 | this.Count -= count; 775 | return; 776 | } 777 | else if (index == Count - count) 778 | { 779 | // Removing from the ending: trim the existing view 780 | this.Count -= count; 781 | return; 782 | } 783 | 784 | if ((index + (count / 2)) < Count / 2) 785 | { 786 | // Removing from first half of list 787 | 788 | // Move items up: 789 | // [0, index) -> [count, count + index) 790 | int copyCount = index; 791 | int writeIndex = count; 792 | for (int j = 0; j < copyCount; j++) 793 | { 794 | buffer[toBufferIndex(writeIndex + j)] 795 | = buffer[toBufferIndex(j)]; 796 | } 797 | 798 | // Rotate to new view 799 | this.shiftStartOffset(count); 800 | } 801 | else 802 | { 803 | // Removing from second half of list 804 | 805 | // Move items down: 806 | // [index + collectionCount, count) -> 807 | // [index, count - collectionCount) 808 | int copyCount = Count - count - index; 809 | int readIndex = index + count; 810 | for (int j = 0; j < copyCount; ++j) 811 | { 812 | buffer[toBufferIndex(index + j)] = 813 | buffer[toBufferIndex(readIndex + j)]; 814 | } 815 | } 816 | 817 | // Adjust valid count 818 | decrementCount(count); 819 | } 820 | 821 | /// 822 | /// Gets the value at the specified index of the Deque 823 | /// 824 | /// The index of the Deque. 825 | /// 826 | public T Get(int index) 827 | { 828 | checkIndexOutOfRange(index); 829 | return buffer[toBufferIndex(index)]; 830 | } 831 | 832 | /// 833 | /// Sets the value at the specified index of the 834 | /// Deque to the given item. 835 | /// 836 | /// The index of the deque to set the item. 837 | /// The item to set at the specified index. 838 | public void Set(int index, T item) 839 | { 840 | checkIndexOutOfRange(index); 841 | buffer[toBufferIndex(index)] = item; 842 | } 843 | 844 | } 845 | } 846 | -------------------------------------------------------------------------------- /Assets/Deque/Deque.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97350c8eff129ad4ba07cb557494516b 3 | timeCreated: 1478274750 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Deque/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DequeUtility 7 | { 8 | internal class Utility 9 | { 10 | public static int ClosestPowerOfTwoGreaterThan(int x) 11 | { 12 | x--; 13 | x |= (x >> 1); 14 | x |= (x >> 2); 15 | x |= (x >> 4); 16 | x |= (x >> 8); 17 | x |= (x >> 16); 18 | return (x+1); 19 | } 20 | 21 | /// 22 | /// Jon Skeet's excellent reimplementation of LINQ Count. 23 | /// 24 | /// The source type. 25 | /// The source IEnumerable. 26 | /// The number of items in the source. 27 | public static int Count(IEnumerable source) 28 | { 29 | if (source == null) 30 | { 31 | throw new ArgumentNullException("source"); 32 | } 33 | 34 | // Optimization for ICollection 35 | ICollection genericCollection = source as ICollection; 36 | if (genericCollection != null) 37 | { 38 | return genericCollection.Count; 39 | } 40 | 41 | // Optimization for ICollection 42 | ICollection nonGenericCollection = source as ICollection; 43 | if (nonGenericCollection != null) 44 | { 45 | return nonGenericCollection.Count; 46 | } 47 | 48 | // Do it the slow way - and make sure we overflow appropriately 49 | checked 50 | { 51 | int count = 0; 52 | using (var iterator = source.GetEnumerator()) 53 | { 54 | while (iterator.MoveNext()) 55 | { 56 | count++; 57 | } 58 | } 59 | return count; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Assets/Deque/Utility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b598a3cb2745e904d90f7bc6b4143aea 3 | timeCreated: 1478274750 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64706da400f49014fa59bb267cf33215 3 | folderAsset: yes 4 | timeCreated: 1520172218 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/LocalVideoMat.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: LocalVideoMat 10 | m_Shader: {fileID: 4800000, guid: 9db3102d32df0d54f99373adc5d885f9, type: 3} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | - _SomeTex: 58 | m_Texture: {fileID: 0} 59 | m_Scale: {x: 1, y: 1} 60 | m_Offset: {x: 0, y: 0} 61 | - _SpecGlossMap: 62 | m_Texture: {fileID: 0} 63 | m_Scale: {x: 1, y: 1} 64 | m_Offset: {x: 0, y: 0} 65 | - _UTex: 66 | m_Texture: {fileID: 0} 67 | m_Scale: {x: 1, y: 1} 68 | m_Offset: {x: 0, y: 0} 69 | - _VTex: 70 | m_Texture: {fileID: 0} 71 | m_Scale: {x: 1, y: 1} 72 | m_Offset: {x: 0, y: 0} 73 | - _YTex: 74 | m_Texture: {fileID: 0} 75 | m_Scale: {x: 1, y: 1} 76 | m_Offset: {x: 0, y: 0} 77 | m_Floats: 78 | - _BumpScale: 1 79 | - _Cutoff: 0.5 80 | - _Cx: 641.926 81 | - _Cy: 359.116 82 | - _DetailNormalMapScale: 1 83 | - _DstBlend: 0 84 | - _Fx: 1043.13 85 | - _Fy: 1038.62 86 | - _GlossMapScale: 1 87 | - _Glossiness: 0.5 88 | - _GlossyReflections: 1 89 | - _K0: 0.246231 90 | - _K1: -0.727204 91 | - _K2: 0.726065 92 | - _Metallic: 0 93 | - _Mode: 0 94 | - _OcclusionStrength: 1 95 | - _Parallax: 0.02 96 | - _SmoothnessTextureChannel: 0 97 | - _SpecularHighlights: 1 98 | - _SrcBlend: 1 99 | - _TexHeight: 720 100 | - _TexWidth: 1280 101 | - _UVSec: 0 102 | - _ZWrite: 1 103 | m_Colors: 104 | - _Color: {r: 1, g: 1, b: 1, a: 1} 105 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 106 | -------------------------------------------------------------------------------- /Assets/Materials/LocalVideoMat.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a10fb88d35416804b85825fb3d6284c7 3 | timeCreated: 1520172198 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 2100000 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/RemoteVideoMat.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: RemoteVideoMat 10 | m_Shader: {fileID: 4800000, guid: 9db3102d32df0d54f99373adc5d885f9, type: 3} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | - _SomeTex: 58 | m_Texture: {fileID: 0} 59 | m_Scale: {x: 1, y: 1} 60 | m_Offset: {x: 0, y: 0} 61 | - _UTex: 62 | m_Texture: {fileID: 0} 63 | m_Scale: {x: 1, y: 1} 64 | m_Offset: {x: 0, y: 0} 65 | - _VTex: 66 | m_Texture: {fileID: 0} 67 | m_Scale: {x: 1, y: 1} 68 | m_Offset: {x: 0, y: 0} 69 | - _YTex: 70 | m_Texture: {fileID: 0} 71 | m_Scale: {x: 1, y: 1} 72 | m_Offset: {x: 0, y: 0} 73 | m_Floats: 74 | - _BumpScale: 1 75 | - _Cutoff: 0.5 76 | - _Cx: 641.926 77 | - _Cy: 359.116 78 | - _DetailNormalMapScale: 1 79 | - _DstBlend: 0 80 | - _Fx: 1043.13 81 | - _Fy: 1038.62 82 | - _GlossMapScale: 1 83 | - _Glossiness: 0.5 84 | - _GlossyReflections: 1 85 | - _K0: 0.246231 86 | - _K1: -0.727204 87 | - _K2: 0.726065 88 | - _Metallic: 0 89 | - _Mode: 0 90 | - _OcclusionStrength: 1 91 | - _Parallax: 0.02 92 | - _SmoothnessTextureChannel: 0 93 | - _SpecularHighlights: 1 94 | - _SrcBlend: 1 95 | - _TexHeight: 720 96 | - _TexWidth: 1280 97 | - _UVSec: 0 98 | - _ZWrite: 1 99 | m_Colors: 100 | - _Color: {r: 1, g: 1, b: 1, a: 1} 101 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 102 | -------------------------------------------------------------------------------- /Assets/Materials/RemoteVideoMat.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 269d29432592e5f4b82950222cfa2985 3 | timeCreated: 1520172208 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 2100000 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/YUV2RGBShader.shader: -------------------------------------------------------------------------------- 1 | Shader "Tango/YUV2RGB" 2 | { 3 | 4 | // from https://github.com/googlearchive/tango-examples-unity/blob/master/UnityExamples/Assets/TangoPrefabs/Shaders/YUV2RGB.shader 5 | // Apache 2.0 License 6 | 7 | Properties 8 | { 9 | _YTex ("Y channel texture", 2D) = "white" {} 10 | _UTex ("U channel texture", 2D) = "white" {} 11 | _VTex ("V channel texture", 2D) = "white" {} 12 | _TexWidth ("texture width", Float) = 1280.0 13 | _TexHeight ("texture height", Float) = 720.0 14 | _Fx ("Fx", Float) = 1043.130005 15 | _Fy ("Fy", Float) = 1038.619995 16 | _Cx ("Cx", Float) = 641.926025 17 | _Cy ("Cy", Float) = 359.115997 18 | _K0 ("K0", Float) = 0.246231 19 | _K1 ("K1", Float) = -0.727204 20 | _K2 ("K2", Float) = 0.726065 21 | } 22 | SubShader 23 | { 24 | // Setting the z write off to make sure our video overlay is always rendered at back. 25 | ZWrite Off 26 | ZTest Off 27 | Tags { "Queue" = "Background" } 28 | Pass 29 | { 30 | CGPROGRAM 31 | #pragma multi_compile _ DISTORTION_ON 32 | 33 | #pragma vertex vert 34 | #pragma fragment frag 35 | 36 | struct appdata 37 | { 38 | float4 vertex : POSITION; 39 | float2 uv : TEXCOORD0; 40 | }; 41 | 42 | struct v2f 43 | { 44 | float4 vertex : SV_POSITION; 45 | float2 uv : TEXCOORD0; 46 | }; 47 | 48 | v2f vert (appdata v) 49 | { 50 | v2f o; 51 | // We don't apply any projection or view matrix here to make sure that 52 | // the geometry is rendered in the screen space. 53 | o.vertex = v.vertex; 54 | o.uv = v.uv; 55 | return o; 56 | } 57 | 58 | // The Y, U, V texture. 59 | // However, at present U and V textures are interleaved into the same texture, 60 | // so we'll only sample from _YTex and _UTex. 61 | sampler2D _YTex; 62 | sampler2D _UTex; 63 | 64 | // Width of the RGBA texture, this is for indexing the channel of color, not 65 | // for scaling. 66 | float _TexWidth; 67 | float _TexHeight; 68 | float _Fx; 69 | float _Fy; 70 | float _Cx; 71 | float _Cy; 72 | float _K0; 73 | float _K1; 74 | float _K2; 75 | 76 | // Compute a modulo b. 77 | float custom_mod(float x, float y) 78 | { 79 | return x - (y * floor(x / y)); 80 | } 81 | 82 | fixed4 frag (v2f i) : SV_Target 83 | { 84 | float undistored_x = i.uv.x; 85 | float undistored_y = i.uv.y; 86 | float x = i.uv.x; 87 | float y = i.uv.y; 88 | 89 | #ifdef DISTORTION_ON 90 | x = (x * _TexWidth - _Cx) / _Fx; 91 | y = (y * _TexHeight - _Cy) / _Fy; 92 | 93 | float r2 = x * x + y * y; 94 | float icdist = 1.0 + r2 * (_K0 + r2 * (_K1 + r2 * _K2)); 95 | undistored_x = x * icdist; 96 | undistored_y = y * icdist; 97 | 98 | undistored_x = (undistored_x * _Fx + _Cx) / _TexWidth; 99 | undistored_y = (undistored_y * _Fy + _Cy) / _TexHeight; 100 | #endif 101 | 102 | // In this example, we are using HAL_PIXEL_FORMAT_YCrCb_420_SP format 103 | // the data packing is: texture_y will pack 1280x720 pixels into 104 | // a 320x720 RGBA8888 texture. 105 | // texture_Cb and texture_Cr will contain copies of the 2x2 downsampled 106 | // interleaved UV planes packed similarly. 107 | float y_value, u_value, v_value; 108 | 109 | float texel_x = undistored_x * _TexWidth; 110 | 111 | // Compute packed-pixel offset for Y value. 112 | float packed_offset = floor(custom_mod(texel_x, 4.0)); 113 | 114 | // Avoid floating point precision problems: Make sure we're sampling from the 115 | // same pixel as we've computed packed_offset for. 116 | undistored_x = (floor(texel_x) + 0.5) / _TexWidth; 117 | 118 | float4 packed_y = tex2D(_YTex, float2(undistored_x, (1.0 - undistored_y))); 119 | if (packed_offset == 0) 120 | { 121 | y_value = packed_y.r; 122 | } 123 | else if (packed_offset == 1) 124 | { 125 | y_value = packed_y.g; 126 | } 127 | else if (packed_offset == 2) 128 | { 129 | y_value = packed_y.b; 130 | } 131 | else 132 | { 133 | y_value = packed_y.a; 134 | } 135 | 136 | float4 packed_uv = tex2D(_UTex, float2(undistored_x, (1.0 - undistored_y))); 137 | 138 | if (packed_offset == 0 || packed_offset == 1) 139 | { 140 | v_value = packed_uv.r; 141 | u_value = packed_uv.g; 142 | } 143 | else 144 | { 145 | v_value = packed_uv.b; 146 | u_value = packed_uv.a; 147 | } 148 | 149 | // The YUV to RBA conversion, please refer to: http://en.wikipedia.org/wiki/YUV 150 | // Y'UV420sp (NV21) to RGB conversion (Android) section. 151 | float r = y_value + 1.370705 * (v_value - 0.5); 152 | float g = y_value - 0.698001 * (v_value - 0.5) - (0.337633 * (u_value - 0.5)); 153 | float b = y_value + 1.732446 * (u_value - 0.5); 154 | 155 | return float4(r, g, b, 1.0); 156 | } 157 | ENDCG 158 | } 159 | } 160 | } -------------------------------------------------------------------------------- /Assets/Materials/YUV2RGBShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60a74a4e1e4196543bd6c5295cb62efa 3 | timeCreated: 1521293787 4 | licenseType: Free 5 | ShaderImporter: 6 | externalObjects: {} 7 | defaultTextures: [] 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 96eadae796b0a64479551b841bf611e7 3 | folderAsset: yes 4 | timeCreated: 1518711026 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 890b4c94e63ff1e44bdc06c42fa40722 3 | folderAsset: yes 4 | timeCreated: 1518711026 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/AndroidManifest.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43613a3c5c34f7c43973ff0b550ca8af 3 | timeCreated: 1519656729 4 | licenseType: Free 5 | TextScriptImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/libs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4869f349ca763fe47962a5a8b0c926cd 3 | folderAsset: yes 4 | timeCreated: 1519569991 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/libs/armeabi-v7a.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9c8b160ed379a242b7651c3fee3a4b9 3 | folderAsset: yes 4 | timeCreated: 1519569991 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/libs/armeabi-v7a/libjingle_peerconnection_so.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Plugins/Android/libs/armeabi-v7a/libjingle_peerconnection_so.so -------------------------------------------------------------------------------- /Assets/Plugins/Android/libs/armeabi-v7a/libjingle_peerconnection_so.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3e880e2ba6318c4c9c4394396ba886a 3 | timeCreated: 1520085180 4 | licenseType: Free 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | '': Any 15 | second: 16 | enabled: 0 17 | settings: 18 | Exclude Android: 0 19 | Exclude Editor: 1 20 | Exclude Linux: 1 21 | Exclude Linux64: 1 22 | Exclude LinuxUniversal: 1 23 | Exclude OSXUniversal: 1 24 | Exclude Win: 1 25 | Exclude Win64: 1 26 | - first: 27 | Android: Android 28 | second: 29 | enabled: 1 30 | settings: 31 | CPU: ARMv7 32 | - first: 33 | Any: 34 | second: 35 | enabled: 0 36 | settings: {} 37 | - first: 38 | Editor: Editor 39 | second: 40 | enabled: 0 41 | settings: 42 | CPU: AnyCPU 43 | DefaultValueInitialized: true 44 | OS: AnyOS 45 | - first: 46 | Facebook: Win 47 | second: 48 | enabled: 0 49 | settings: 50 | CPU: AnyCPU 51 | - first: 52 | Facebook: Win64 53 | second: 54 | enabled: 0 55 | settings: 56 | CPU: AnyCPU 57 | - first: 58 | Standalone: Linux 59 | second: 60 | enabled: 0 61 | settings: 62 | CPU: x86 63 | - first: 64 | Standalone: Linux64 65 | second: 66 | enabled: 0 67 | settings: 68 | CPU: x86_64 69 | - first: 70 | Standalone: LinuxUniversal 71 | second: 72 | enabled: 0 73 | settings: 74 | CPU: None 75 | - first: 76 | Standalone: OSXUniversal 77 | second: 78 | enabled: 0 79 | settings: 80 | CPU: AnyCPU 81 | - first: 82 | Standalone: Win 83 | second: 84 | enabled: 0 85 | settings: 86 | CPU: AnyCPU 87 | - first: 88 | Standalone: Win64 89 | second: 90 | enabled: 0 91 | settings: 92 | CPU: AnyCPU 93 | userData: 94 | assetBundleName: 95 | assetBundleVariant: 96 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/libwebrtc_unity.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Plugins/Android/libwebrtc_unity.jar -------------------------------------------------------------------------------- /Assets/Plugins/Android/libwebrtc_unity.jar.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b413cd6c0a74014cbd35cf0727cb60f 3 | timeCreated: 1520085180 4 | licenseType: Free 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | Android: Android 15 | second: 16 | enabled: 1 17 | settings: {} 18 | - first: 19 | Any: 20 | second: 21 | enabled: 0 22 | settings: {} 23 | - first: 24 | Editor: Editor 25 | second: 26 | enabled: 0 27 | settings: 28 | DefaultValueInitialized: true 29 | userData: 30 | assetBundleName: 31 | assetBundleVariant: 32 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/mainTemplate.gradle_: -------------------------------------------------------------------------------- 1 | // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN 2 | buildscript { 3 | repositories { 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.1.0' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | flatDir { 15 | dirs 'libs' 16 | } 17 | } 18 | } 19 | 20 | apply plugin: 'com.android.application' 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | } 25 | 26 | android { 27 | compileSdkVersion 26 28 | buildToolsVersion '27.0.3' 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | 34 | defaultConfig { 35 | targetSdkVersion 24 36 | applicationId 'com.makoto.WebRtcDll' 37 | //jackOptions { 38 | // enabled true 39 | //} 40 | } 41 | 42 | lintOptions { 43 | abortOnError false 44 | } 45 | 46 | aaptOptions { 47 | noCompress '.unity3d', '.ress', '.resource', '.obb' 48 | } 49 | 50 | 51 | buildTypes { 52 | debug { 53 | minifyEnabled false 54 | useProguard false 55 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt' 56 | jniDebuggable true 57 | } 58 | release { 59 | minifyEnabled false 60 | useProguard false 61 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt' 62 | signingConfig signingConfigs.debug 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Assets/Plugins/Android/mainTemplate.gradle_.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1bc97edf12e40046982a0f5c9743aef 3 | timeCreated: 1519743144 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b123a4965be12a644a7dfe364ce21733 3 | folderAsset: yes 4 | timeCreated: 1523175757 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/SampleMaterial.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: SampleMaterial 10 | m_Shader: {fileID: 4800000, guid: 9db3102d32df0d54f99373adc5d885f9, type: 3} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | - _SomeTex: 58 | m_Texture: {fileID: 2800000, guid: 1b1efdf07553a9749bbb5d3204ff2510, type: 3} 59 | m_Scale: {x: 1, y: 1} 60 | m_Offset: {x: 0, y: 0} 61 | m_Floats: 62 | - _BumpScale: 1 63 | - _Cutoff: 0.5 64 | - _DetailNormalMapScale: 1 65 | - _DstBlend: 0 66 | - _GlossMapScale: 1 67 | - _Glossiness: 0.5 68 | - _GlossyReflections: 1 69 | - _Metallic: 0 70 | - _Mode: 0 71 | - _OcclusionStrength: 1 72 | - _Parallax: 0.02 73 | - _SmoothnessTextureChannel: 0 74 | - _SpecularHighlights: 1 75 | - _SrcBlend: 1 76 | - _UVSec: 0 77 | - _ZWrite: 1 78 | m_Colors: 79 | - _Color: {r: 0.9117647, g: 0.120674744, b: 0.120674744, a: 1} 80 | - _ColorA: {r: 0.14850318, g: 0.0864511, b: 0.9044118, a: 1} 81 | - _ColorX: {r: 0.54610133, g: 0.41630623, b: 0.7352941, a: 1} 82 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 83 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/SampleMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f9865c655a54524bb2ad5cb8b191894 3 | timeCreated: 1523175822 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 2100000 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/SampleShader1.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/SampleShader1" { 2 | Properties { 3 | _MainTex("Main Tex", 2D) = "white" {} 4 | } 5 | SubShader { 6 | Tags { "RenderType" = "Opaque" } 7 | CGPROGRAM 8 | #pragma surface surf Lambert //alpha 9 | struct Input { 10 | float2 uv_MainTex; 11 | }; 12 | sampler2D _MainTex; 13 | float3 yuv2rgb(float3 yuv) { 14 | // The YUV to RBA conversion, please refer to: http://en.wikipedia.org/wiki/YUV 15 | // Y'UV420sp (NV21) to RGB conversion (Android) section. 16 | float y_value = yuv[0]; 17 | float u_value = yuv[1]; 18 | float v_value = yuv[2]; 19 | float r = y_value + 1.370705 * (v_value - 0.5); 20 | float g = y_value - 0.698001 * (v_value - 0.5) - (0.337633 * (u_value - 0.5)); 21 | float b = y_value + 1.732446 * (u_value - 0.5); 22 | return float3(r, g, b); 23 | } 24 | void surf (Input IN, inout SurfaceOutput o) { 25 | o.Albedo = yuv2rgb(tex2D(_MainTex, IN.uv_MainTex).rgb); 26 | } 27 | ENDCG 28 | } 29 | Fallback "Diffuse" 30 | } 31 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/SampleShader1.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9db3102d32df0d54f99373adc5d885f9 3 | timeCreated: 1523175813 4 | licenseType: Free 5 | ShaderImporter: 6 | externalObjects: {} 7 | defaultTextures: [] 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Plugins/Shaders/google.png -------------------------------------------------------------------------------- /Assets/Plugins/Shaders/google.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b1efdf07553a9749bbb5d3204ff2510 3 | timeCreated: 1523196886 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | externalObjects: {} 8 | serializedVersion: 4 9 | mipmaps: 10 | mipMapMode: 0 11 | enableMipMap: 1 12 | sRGBTexture: 1 13 | linearTexture: 0 14 | fadeOut: 0 15 | borderMipMap: 0 16 | mipMapsPreserveCoverage: 0 17 | alphaTestReferenceValue: 0.5 18 | mipMapFadeDistanceStart: 1 19 | mipMapFadeDistanceEnd: 3 20 | bumpmap: 21 | convertToNormalMap: 0 22 | externalNormalMap: 0 23 | heightScale: 0.25 24 | normalMapFilter: 0 25 | isReadable: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -1 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 49 | spritePixelsToUnits: 100 50 | alphaUsage: 1 51 | alphaIsTransparency: 0 52 | spriteTessellationDetail: -1 53 | textureType: 0 54 | textureShape: 1 55 | maxTextureSizeSet: 0 56 | compressionQualitySet: 0 57 | textureFormatSet: 0 58 | platformSettings: 59 | - buildTarget: DefaultTexturePlatform 60 | maxTextureSize: 2048 61 | resizeAlgorithm: 0 62 | textureFormat: -1 63 | textureCompression: 1 64 | compressionQuality: 50 65 | crunchedCompression: 0 66 | allowsAlphaSplitting: 0 67 | overridden: 0 68 | androidETC2FallbackOverride: 0 69 | spriteSheet: 70 | serializedVersion: 2 71 | sprites: [] 72 | outline: [] 73 | physicsShape: [] 74 | spritePackingTag: 75 | userData: 76 | assetBundleName: 77 | assetBundleVariant: 78 | -------------------------------------------------------------------------------- /Assets/Socket.IO.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 40f04e633c9e31648be6fed7604d50cc 3 | folderAsset: yes 4 | timeCreated: 1521201948 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Socket.IO/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Socket.IO/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Assets/Socket.IO/Newtonsoft.Json.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b7abff9ae3fc9746ae33b02de5a96a8 3 | timeCreated: 1521201950 4 | licenseType: Free 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | Any: 15 | second: 16 | enabled: 1 17 | settings: {} 18 | - first: 19 | Editor: Editor 20 | second: 21 | enabled: 0 22 | settings: 23 | DefaultValueInitialized: true 24 | - first: 25 | Windows Store Apps: WindowsStoreApps 26 | second: 27 | enabled: 0 28 | settings: 29 | CPU: AnyCPU 30 | userData: 31 | assetBundleName: 32 | assetBundleVariant: 33 | -------------------------------------------------------------------------------- /Assets/Socket.IO/SocketIoClientDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Socket.IO/SocketIoClientDotNet.dll -------------------------------------------------------------------------------- /Assets/Socket.IO/SocketIoClientDotNet.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc063c9ccffa49943adfb3e630d5e9b1 3 | timeCreated: 1521201952 4 | licenseType: Free 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | Any: 15 | second: 16 | enabled: 1 17 | settings: {} 18 | - first: 19 | Editor: Editor 20 | second: 21 | enabled: 0 22 | settings: 23 | DefaultValueInitialized: true 24 | - first: 25 | Windows Store Apps: WindowsStoreApps 26 | second: 27 | enabled: 0 28 | settings: 29 | CPU: AnyCPU 30 | userData: 31 | assetBundleName: 32 | assetBundleVariant: 33 | -------------------------------------------------------------------------------- /Assets/Socket.IO/WebSocket4Net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhama/WebRtcUnityPluginSample/87e562084c03e534925ec7612ab09c5add12c42a/Assets/Socket.IO/WebSocket4Net.dll -------------------------------------------------------------------------------- /Assets/Socket.IO/WebSocket4Net.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c96933b235c83d144bf6c4005e4fe145 3 | timeCreated: 1521215488 4 | licenseType: Free 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | Any: 15 | second: 16 | enabled: 1 17 | settings: {} 18 | - first: 19 | Editor: Editor 20 | second: 21 | enabled: 0 22 | settings: 23 | DefaultValueInitialized: true 24 | - first: 25 | Windows Store Apps: WindowsStoreApps 26 | second: 27 | enabled: 0 28 | settings: 29 | CPU: AnyCPU 30 | userData: 31 | assetBundleName: 32 | assetBundleVariant: 33 | -------------------------------------------------------------------------------- /Assets/WebRTCSample.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a2c7bec840c33a439131d394e275447 3 | folderAsset: yes 4 | timeCreated: 1524072600 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/FramePacket.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class FramePacket 6 | { 7 | public FramePacket(int bufsize) 8 | { 9 | _buffer = new byte[bufsize]; 10 | } 11 | 12 | public int width; 13 | public int height; 14 | private byte[] _buffer; 15 | public byte[] Buffer 16 | { 17 | get { return _buffer; } 18 | } 19 | 20 | public override string ToString() 21 | { 22 | return "FramePacket width, height=(" + width + "," + height + ") buffer size:" + _buffer.Length; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/FramePacket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 855d90e81ad15f84dbfe014f6fb27086 3 | timeCreated: 1521902307 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/FramePacketPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | // 返却されたバッファをできるだけ再利用するバッファプール。 6 | // スレッドセーフ。 7 | public class FramePacketPool 8 | { 9 | private Deque pool = new Deque(); 10 | 11 | // リクエストされたサイズ以上のバッファを返す。 12 | public FramePacket GetDataBuffer(int size) 13 | { 14 | lock (this) 15 | { 16 | // TODO: 1回だけでいいの? 17 | if (pool.Count > 0) 18 | { 19 | FramePacket candidate = pool.RemoveFront(); 20 | if (candidate == null) 21 | { 22 | Debug.LogError("candidate is null! returns new buffer."); 23 | return GetNewBuffer(size); 24 | } 25 | else 26 | { 27 | if (candidate.Buffer == null) 28 | { 29 | Debug.LogError("candidate.Buffer is null!"); 30 | } 31 | } 32 | if (candidate.Buffer.Length > size) 33 | { 34 | return candidate; 35 | } 36 | } 37 | } 38 | return GetNewBuffer(size); 39 | } 40 | 41 | private FramePacket GetNewBuffer(int neededSize) 42 | { 43 | FramePacket packet = new FramePacket((int)(neededSize * 1.2)); 44 | return packet; 45 | } 46 | 47 | // バッファをプールから取り出し、さらにデータをコピーして渡す 48 | public FramePacket GetDataBufferWithContents(int width, int height, byte[] src, int size) 49 | { 50 | FramePacket dest = GetDataBuffer(size); 51 | System.Array.Copy(src, 0, dest.Buffer, 0, size); 52 | dest.width = width; 53 | dest.height = height; 54 | return dest; 55 | } 56 | 57 | // 返却 58 | public void Push(FramePacket packet) 59 | { 60 | lock (this) 61 | { 62 | pool.AddFront(packet); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Assets/WebRTCSample/FramePacketPool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50d0dc188e048d64f84775ebe28d2628 3 | timeCreated: 1521902211 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/FrameQueue.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | 6 | // FramePacket のキュー。 7 | // 指定サイズ以上Pushすると、指定サイズ以下になるよう末尾のデータから削除される。 8 | // スレッドセーフ。 9 | public class FrameQueue 10 | { 11 | private Deque frames = new Deque(); 12 | private FramePacketPool bufferPool = new FramePacketPool(); 13 | private int maxQueueCount; 14 | MovieStats stats = new MovieStats(); 15 | 16 | public FrameQueue(int _maxQueueCount) 17 | { 18 | maxQueueCount = _maxQueueCount; 19 | } 20 | 21 | public void Push(FramePacket frame) 22 | { 23 | stats.CountFrameLoad(); 24 | FramePacket trashBuf = null; 25 | lock (this) 26 | { 27 | frames.AddFront(frame); 28 | if (frames.Count >= maxQueueCount) 29 | { 30 | stats.CountFrameSkip(); 31 | trashBuf = frames.RemoveBack(); 32 | } 33 | } 34 | // lock内でPushしないのは、thisとbufferPoolの両方のlockを同時にとらないようにする配慮。 35 | if (trashBuf != null) 36 | { 37 | bufferPool.Push(trashBuf); 38 | } 39 | } 40 | 41 | public FramePacket Pop() 42 | { 43 | lock (this) 44 | { 45 | if (frames.IsEmpty) 46 | { 47 | return null; 48 | } 49 | stats.CountFrameShow(); 50 | return frames.RemoveBack(); 51 | } 52 | } 53 | 54 | public FramePacket GetDataBufferWithContents(int width, int height, byte[] src, int size) 55 | { 56 | return bufferPool.GetDataBufferWithContents(width, height, src, size); 57 | } 58 | 59 | public FramePacket GetDataBufferWithoutContents(int size) 60 | { 61 | return bufferPool.GetDataBuffer(size); 62 | } 63 | 64 | public void Pool(FramePacket buf) 65 | { 66 | bufferPool.Push(buf); 67 | } 68 | 69 | public int Count 70 | { 71 | get 72 | { 73 | lock (this) 74 | { 75 | return frames.Count; 76 | } 77 | } 78 | } 79 | 80 | public FramePacketPool FramePacketPool 81 | { 82 | get { return bufferPool; } 83 | } 84 | 85 | public MovieStats Stats 86 | { 87 | get { return stats; } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/FrameQueue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e3880dcb4b3d8c549966ead67bc4e7f3 3 | timeCreated: 1521902198 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/MovieStats.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class MovieStats 6 | { 7 | const int maxSamples = 100; 8 | private Deque frameLoadTimes = new Deque(maxSamples + 1); 9 | private Deque frameShowTimes = new Deque(maxSamples + 1); 10 | private Deque frameSkipTimes = new Deque(maxSamples + 1); 11 | System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 12 | 13 | public MovieStats() 14 | { 15 | sw.Start(); 16 | } 17 | 18 | public void CountFrameLoad() 19 | { 20 | AddSampleToQueue(frameLoadTimes); 21 | } 22 | public void CountFrameSkip() 23 | { 24 | AddSampleToQueue(frameSkipTimes); 25 | } 26 | public void CountFrameShow() 27 | { 28 | AddSampleToQueue(frameShowTimes); 29 | } 30 | void AddSampleToQueue(Deque queue) 31 | { 32 | lock (this) 33 | { 34 | queue.AddFront(sw.ElapsedMilliseconds * 0.001f); 35 | if (queue.Count >= maxSamples) 36 | { 37 | queue.RemoveBack(); 38 | } 39 | } 40 | } 41 | public float fpsLoad() 42 | { 43 | return CalcFps(frameLoadTimes); 44 | } 45 | public float fpsSkip() 46 | { 47 | return CalcFps(frameSkipTimes); 48 | } 49 | public float fpsShow() 50 | { 51 | return CalcFps(frameShowTimes); 52 | } 53 | public float CalcFps(Deque queue) 54 | { 55 | int count = 0; 56 | float firstTime = 0; 57 | float lastTime = 0; 58 | lock (this) 59 | { 60 | count = queue.Count; 61 | if (count >= 2) 62 | { 63 | firstTime = queue.Get(0); 64 | lastTime = queue.Get(count - 1); 65 | } 66 | } 67 | if (count <= 1) 68 | { 69 | return 0; 70 | } 71 | float fps = (count - 1) / (firstTime - lastTime); 72 | return fps; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/MovieStats.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dcf990a690345874da7e72ede008befb 3 | timeCreated: 1521902351 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/PeerConnectionM.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | // native impl: 6 | // https://chromium.googlesource.com/external/webrtc/+/51e2046dbcbbb0375c383594aa4f77aa8ed67b06/examples/unityplugin/simple_peer_connection.cc 7 | // https://chromium.googlesource.com/external/webrtc/+/51e2046dbcbbb0375c383594aa4f77aa8ed67b06/examples/unityplugin/unity_plugin_apis.cc 8 | 9 | namespace SimplePeerConnectionM 10 | { 11 | // A class for ice candidate. 12 | public class IceCandidate 13 | { 14 | public IceCandidate(string candidate, int sdpMlineIndex, string sdpMid) 15 | { 16 | mCandidate = candidate; 17 | mSdpMlineIndex = sdpMlineIndex; 18 | mSdpMid = sdpMid; 19 | } 20 | string mCandidate; 21 | int mSdpMlineIndex; 22 | string mSdpMid; 23 | public string Candidate 24 | { 25 | get { return mCandidate; } 26 | set { mCandidate = value; } 27 | } 28 | public int SdpMlineIndex 29 | { 30 | get { return mSdpMlineIndex; } 31 | set { mSdpMlineIndex = value; } 32 | } 33 | public string SdpMid 34 | { 35 | get { return mSdpMid; } 36 | set { mSdpMid = value; } 37 | } 38 | } 39 | // A managed wrapper up class for the native c style peer connection APIs. 40 | public class PeerConnectionM 41 | { 42 | //private const string dllPath = "webrtc_unity_plugin"; 43 | private const string dllPath = "libjingle_peerconnection_so"; 44 | 45 | //[DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 46 | //private static extern int InitializePeerConnection(string[] turnUrls, int noOfUrls, string username, string credential, bool isReceiver); 47 | 48 | //create a peerconnection with turn servers 49 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 50 | private static extern int CreatePeerConnection(string[] turnUrls, int noOfUrls, 51 | string username, string credential); 52 | 53 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 54 | private static extern bool ClosePeerConnection(int peerConnectionId); 55 | 56 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 57 | private static extern bool AddStream(int peerConnectionId, bool audioOnly); 58 | 59 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 60 | private static extern bool AddDataChannel(int peerConnectionId); 61 | 62 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 63 | private static extern bool CreateOffer(int peerConnectionId); 64 | 65 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 66 | private static extern bool CreateAnswer(int peerConnectionId); 67 | 68 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 69 | private static extern bool SendDataViaDataChannel(int peerConnectionId, string data); 70 | 71 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 72 | private static extern bool SetAudioControl(int peerConnectionId, bool isMute, bool isRecord); 73 | 74 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 75 | private delegate void LocalDataChannelReadyInternalDelegate(); 76 | public delegate void LocalDataChannelReadyDelegate(int id); 77 | 78 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 79 | private static extern bool RegisterOnLocalDataChannelReady( 80 | int peerConnectionId, LocalDataChannelReadyInternalDelegate callback); 81 | 82 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 83 | private delegate void DataFromDataChannelReadyInternalDelegate(string s); 84 | public delegate void DataFromDataChannelReadyDelegate(int id, string s); 85 | 86 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 87 | private static extern bool RegisterOnDataFromDataChannelReady( 88 | int peerConnectionId, DataFromDataChannelReadyInternalDelegate callback); 89 | 90 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 91 | private delegate void FailureMessageInternalDelegate(string msg); 92 | public delegate void FailureMessageDelegate(int id, string msg); 93 | 94 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 95 | private static extern bool RegisterOnFailure(int peerConnectionId, 96 | FailureMessageInternalDelegate callback); 97 | 98 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 99 | private delegate void AudioBusReadyInternalDelegate(IntPtr data, int bitsPerSample, 100 | int sampleRate, int numberOfChannels, int numberOfFrames); 101 | public delegate void AudioBusReadyDelegate(int id, IntPtr data, int bitsPerSample, 102 | int sampleRate, int numberOfChannels, int numberOfFrames); 103 | 104 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 105 | private static extern bool RegisterOnAudioBusReady(int peerConnectionId, 106 | AudioBusReadyInternalDelegate callback); 107 | 108 | // Video callbacks. 109 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 110 | private delegate void I420FrameReadyInternalDelegate( 111 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 112 | int strideY, int strideU, int strideV, int strideA, 113 | uint width, uint height); 114 | public delegate void I420FrameReadyDelegate(int id, 115 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 116 | int strideY, int strideU, int strideV, int strideA, 117 | uint width, uint height); 118 | 119 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 120 | private static extern bool RegisterOnLocalI420FrameReady(int peerConnectionId, 121 | I420FrameReadyInternalDelegate callback); 122 | 123 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 124 | private static extern bool RegisterOnRemoteI420FrameReady(int peerConnectionId, 125 | I420FrameReadyInternalDelegate callback); 126 | 127 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 128 | private delegate void LocalSdpReadytoSendInternalDelegate(string type, string sdp); 129 | public delegate void LocalSdpReadytoSendDelegate(int id, string type, string sdp); 130 | 131 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 132 | private static extern bool RegisterOnLocalSdpReadytoSend(int peerConnectionId, 133 | LocalSdpReadytoSendInternalDelegate callback); 134 | 135 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 136 | private delegate void IceCandiateReadytoSendInternalDelegate( 137 | string candidate, int sdpMlineIndex, string sdpMid); 138 | public delegate void IceCandiateReadytoSendDelegate( 139 | int id, string candidate, int sdpMlineIndex, string sdpMid); 140 | 141 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 142 | private static extern bool RegisterOnIceCandiateReadytoSend( 143 | int peerConnectionId, IceCandiateReadytoSendInternalDelegate callback); 144 | 145 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 146 | private static extern bool SetRemoteDescription(int peerConnectionId, string type, string sdp); 147 | 148 | [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)] 149 | private static extern bool AddIceCandidate(int peerConnectionId, string sdp, 150 | int sdpMlineindex, string sdpMid); 151 | public PeerConnectionM(List turnUrls, string username, string credential) 152 | { 153 | string[] urls = turnUrls != null ? turnUrls.ToArray() : null; 154 | int length = turnUrls != null ? turnUrls.Count : 0; 155 | mPeerConnectionId = CreatePeerConnection(urls, length, username, credential); 156 | RegisterCallbacks(); 157 | } 158 | public void ClosePeerConnection() 159 | { 160 | ClosePeerConnection(mPeerConnectionId); 161 | mPeerConnectionId = -1; 162 | } 163 | // Return -1 if Peerconnection is not available. 164 | public int GetUniqueId() 165 | { 166 | return mPeerConnectionId; 167 | } 168 | public void AddStream(bool audioOnly) 169 | { 170 | AddStream(mPeerConnectionId, audioOnly); 171 | } 172 | public void AddDataChannel() 173 | { 174 | AddDataChannel(mPeerConnectionId); 175 | } 176 | public void CreateOffer() 177 | { 178 | CreateOffer(mPeerConnectionId); 179 | } 180 | public void CreateAnswer() 181 | { 182 | CreateAnswer(mPeerConnectionId); 183 | } 184 | public void SendDataViaDataChannel(string data) 185 | { 186 | SendDataViaDataChannel(mPeerConnectionId, data); 187 | } 188 | public void SetAudioControl(bool isMute, bool isRecord) 189 | { 190 | SetAudioControl(mPeerConnectionId, isMute, isRecord); 191 | } 192 | public void SetRemoteDescription(string type, string sdp) 193 | { 194 | SetRemoteDescription(mPeerConnectionId, type, sdp); 195 | } 196 | public void AddIceCandidate(string candidate, int sdpMlineindex, string sdpMid) 197 | { 198 | AddIceCandidate(mPeerConnectionId, candidate, sdpMlineindex, sdpMid); 199 | } 200 | private void RegisterCallbacks() 201 | { 202 | localDataChannelReadyDelegate = new LocalDataChannelReadyInternalDelegate( 203 | RaiseLocalDataChannelReady); 204 | RegisterOnLocalDataChannelReady(mPeerConnectionId, localDataChannelReadyDelegate); 205 | dataFromDataChannelReadyDelegate = new DataFromDataChannelReadyInternalDelegate( 206 | RaiseDataFromDataChannelReady); 207 | RegisterOnDataFromDataChannelReady(mPeerConnectionId, dataFromDataChannelReadyDelegate); 208 | failureMessageDelegate = new FailureMessageInternalDelegate(RaiseFailureMessage); 209 | RegisterOnFailure(mPeerConnectionId, failureMessageDelegate); 210 | audioBusReadyDelegate = new AudioBusReadyInternalDelegate(RaiseAudioBusReady); 211 | RegisterOnAudioBusReady(mPeerConnectionId, audioBusReadyDelegate); 212 | localI420FrameReadyDelegate = new I420FrameReadyInternalDelegate( 213 | RaiseLocalVideoFrameReady); 214 | RegisterOnLocalI420FrameReady(mPeerConnectionId, localI420FrameReadyDelegate); 215 | remoteI420FrameReadyDelegate = new I420FrameReadyInternalDelegate( 216 | RaiseRemoteVideoFrameReady); 217 | RegisterOnRemoteI420FrameReady(mPeerConnectionId, remoteI420FrameReadyDelegate); 218 | localSdpReadytoSendDelegate = new LocalSdpReadytoSendInternalDelegate( 219 | RaiseLocalSdpReadytoSend); 220 | RegisterOnLocalSdpReadytoSend(mPeerConnectionId, localSdpReadytoSendDelegate); 221 | iceCandiateReadytoSendDelegate = 222 | new IceCandiateReadytoSendInternalDelegate(RaiseIceCandiateReadytoSend); 223 | RegisterOnIceCandiateReadytoSend( 224 | mPeerConnectionId, iceCandiateReadytoSendDelegate); 225 | } 226 | private void RaiseLocalDataChannelReady() 227 | { 228 | if (OnLocalDataChannelReady != null) 229 | OnLocalDataChannelReady(mPeerConnectionId); 230 | } 231 | private void RaiseDataFromDataChannelReady(string data) 232 | { 233 | if (OnDataFromDataChannelReady != null) 234 | OnDataFromDataChannelReady(mPeerConnectionId, data); 235 | } 236 | private void RaiseFailureMessage(string msg) 237 | { 238 | if (OnFailureMessage != null) 239 | OnFailureMessage(mPeerConnectionId, msg); 240 | } 241 | private void RaiseAudioBusReady(IntPtr data, int bitsPerSample, 242 | int sampleRate, int numberOfChannels, int numberOfFrames) 243 | { 244 | if (OnAudioBusReady != null) 245 | OnAudioBusReady(mPeerConnectionId, data, bitsPerSample, sampleRate, 246 | numberOfChannels, numberOfFrames); 247 | } 248 | private void RaiseLocalVideoFrameReady( 249 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 250 | int strideY, int strideU, int strideV, int strideA, 251 | uint width, uint height) 252 | { 253 | if (OnLocalVideoFrameReady != null) 254 | OnLocalVideoFrameReady(mPeerConnectionId, dataY, dataU, dataV, dataA, strideY, strideU, strideV, strideA, 255 | width, height); 256 | } 257 | private void RaiseRemoteVideoFrameReady( 258 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 259 | int strideY, int strideU, int strideV, int strideA, 260 | uint width, uint height) 261 | { 262 | if (OnRemoteVideoFrameReady != null) 263 | OnRemoteVideoFrameReady(mPeerConnectionId, dataY, dataU, dataV, dataA, strideY, strideU, strideV, strideA, 264 | width, height); 265 | } 266 | private void RaiseLocalSdpReadytoSend(string type, string sdp) 267 | { 268 | if (OnLocalSdpReadytoSend != null) 269 | OnLocalSdpReadytoSend(mPeerConnectionId, type, sdp); 270 | } 271 | private void RaiseIceCandiateReadytoSend(string candidate, int sdpMlineIndex, string sdpMid) 272 | { 273 | if (OnIceCandiateReadytoSend != null) 274 | OnIceCandiateReadytoSend(mPeerConnectionId, candidate, sdpMlineIndex, sdpMid); 275 | } 276 | public void AddQueuedIceCandidate(List iceCandidateQueue) 277 | { 278 | if (iceCandidateQueue != null) 279 | { 280 | foreach (IceCandidate ic in iceCandidateQueue) 281 | { 282 | AddIceCandidate(mPeerConnectionId, ic.Candidate, ic.SdpMlineIndex, ic.SdpMid); 283 | } 284 | } 285 | } 286 | private LocalDataChannelReadyInternalDelegate localDataChannelReadyDelegate = null; 287 | public event LocalDataChannelReadyDelegate OnLocalDataChannelReady; 288 | private DataFromDataChannelReadyInternalDelegate dataFromDataChannelReadyDelegate = null; 289 | public event DataFromDataChannelReadyDelegate OnDataFromDataChannelReady; 290 | private FailureMessageInternalDelegate failureMessageDelegate = null; 291 | public event FailureMessageDelegate OnFailureMessage; 292 | private AudioBusReadyInternalDelegate audioBusReadyDelegate = null; 293 | public event AudioBusReadyDelegate OnAudioBusReady; 294 | private I420FrameReadyInternalDelegate localI420FrameReadyDelegate = null; 295 | public event I420FrameReadyDelegate OnLocalVideoFrameReady; 296 | private I420FrameReadyInternalDelegate remoteI420FrameReadyDelegate = null; 297 | public event I420FrameReadyDelegate OnRemoteVideoFrameReady; 298 | private LocalSdpReadytoSendInternalDelegate localSdpReadytoSendDelegate = null; 299 | public event LocalSdpReadytoSendDelegate OnLocalSdpReadytoSend; 300 | private IceCandiateReadytoSendInternalDelegate iceCandiateReadytoSendDelegate = null; 301 | public event IceCandiateReadytoSendDelegate OnIceCandiateReadytoSend; 302 | private int mPeerConnectionId = -1; 303 | } 304 | } -------------------------------------------------------------------------------- /Assets/WebRTCSample/PeerConnectionM.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2938c0085ad6e5b4fa20e78a5d20b234 3 | timeCreated: 1518628198 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fba404ebdb31c84ea5907e515da1570 3 | folderAsset: yes 4 | timeCreated: 1524072671 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/UI/ConnectButton.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | public class ConnectButton : MonoBehaviour { 7 | 8 | public InputField urlInput; 9 | public WebRtcNativeCallSample webrtc; 10 | 11 | // Use this for initialization 12 | void Start () { 13 | string serverUrl = PlayerPrefs.GetString("serverUrl"); 14 | if (serverUrl != null) 15 | { 16 | urlInput.text = serverUrl; 17 | } 18 | if (urlInput.text == null || urlInput.text == "") 19 | { 20 | urlInput.text = webrtc.serverURL; 21 | } 22 | } 23 | 24 | // Update is called once per frame 25 | void Update () { 26 | 27 | } 28 | 29 | public void ButtonPushed() 30 | { 31 | string serverUrl = urlInput.text; 32 | webrtc.serverURL = serverUrl; 33 | webrtc.ConnectToServer(); 34 | PlayerPrefs.SetString("serverUrl", serverUrl); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/UI/ConnectButton.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 37bc66b301ad83e41974c50cce1846ab 3 | timeCreated: 1521311378 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/UI/StatusLabel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | public class StatusLabel : MonoBehaviour { 7 | 8 | public WebRtcNativeCallSample webrtc; 9 | Text text; 10 | 11 | // Use this for initialization 12 | void Start () { 13 | text = GetComponent(); 14 | 15 | } 16 | 17 | // Update is called once per frame 18 | void Update () { 19 | var status = "Status: " + webrtc.status; 20 | if (text.text != status) 21 | { 22 | text.text = status; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/UI/StatusLabel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9694a0c9bffccd4eb8955a5e00c0a24 3 | timeCreated: 1524068911 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcNativeCallSample.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using SimplePeerConnectionM; 5 | using System; 6 | using System.Runtime.InteropServices; 7 | using System.Threading; 8 | 9 | public class WebRtcNativeCallSample : MonoBehaviour { 10 | 11 | bool first = true; 12 | Texture2D textureLocal; 13 | Texture2D textureRemote; 14 | public Material localTargetMaterial; 15 | public Material remoteTargetMaterial; 16 | public FrameQueue frameQueueLocal = new FrameQueue(3); 17 | public FrameQueue frameQueueRemote = new FrameQueue(5); 18 | public WebRtcVideoPlayer localPlayer; 19 | public WebRtcVideoPlayer remotePlayer; 20 | public string status; 21 | 22 | PeerConnectionM peer; 23 | string offerSdp; 24 | string answerSdp; 25 | List iceCandidates; 26 | 27 | 28 | // Use this for initialization 29 | void Start() { 30 | Debug.Log("Sample.Start() + " + " thread: " + Thread.CurrentThread.ManagedThreadId + ":" + Thread.CurrentThread.Name); 31 | if (localPlayer != null) 32 | { 33 | localPlayer.frameQueue = frameQueueLocal; 34 | } 35 | if (remotePlayer != null) 36 | { 37 | remotePlayer.frameQueue = frameQueueRemote; 38 | } 39 | } 40 | 41 | public void InitWebRTC() { 42 | iceCandidates = new List(); 43 | 44 | #if UNITY_ANDROID 45 | AndroidJavaClass systemClass = new AndroidJavaClass("java.lang.System"); 46 | string libname = "jingle_peerconnection_so"; 47 | systemClass.CallStatic("loadLibrary", new object[1] { libname }); 48 | Debug.Log("loadLibrary loaded : " + libname); 49 | 50 | /* 51 | * Below is equivalent of this java code: 52 | * PeerConnectionFactory.InitializationOptions.Builder builder = 53 | * PeerConnectionFactory.InitializationOptions.builder(UnityPlayer.currentActivity); 54 | * PeerConnectionFactory.InitializationOptions options = 55 | * builder.createInitializationOptions(); 56 | * PeerConnectionFactory.initialize(options); 57 | */ 58 | 59 | AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 60 | AndroidJavaObject activity = playerClass.GetStatic("currentActivity"); 61 | AndroidJavaClass webrtcClass = new AndroidJavaClass("org.webrtc.PeerConnectionFactory"); 62 | AndroidJavaClass initOptionsClass = new AndroidJavaClass("org.webrtc.PeerConnectionFactory$InitializationOptions"); 63 | AndroidJavaObject builder = initOptionsClass.CallStatic("builder", new object[1] { activity }); 64 | AndroidJavaObject options = builder.Call("createInitializationOptions"); 65 | if (webrtcClass != null) 66 | 67 | { 68 | Debug.Log("PeerConnectionFactory.initialize calling"); 69 | webrtcClass.CallStatic("initialize", new object[1] { options }); 70 | Debug.Log("PeerConnectionFactory.initialize called."); 71 | } 72 | 73 | #endif 74 | List servers = new List(); 75 | servers.Add("stun: stun.skyway.io:3478"); 76 | servers.Add("stun: stun.l.google.com:19302"); 77 | peer = new PeerConnectionM(servers, "", ""); 78 | int id = peer.GetUniqueId(); 79 | Debug.Log("PeerConnectionM.GetUniqueId() : " + id); 80 | 81 | peer.OnLocalSdpReadytoSend += OnLocalSdpReadytoSend; 82 | peer.OnIceCandiateReadytoSend += OnIceCandiateReadytoSend; 83 | peer.OnLocalVideoFrameReady += OnI420LocalFrameReady; 84 | peer.OnRemoteVideoFrameReady += OnI420RemoteFrameReady; 85 | peer.OnFailureMessage += OnFailureMessage; 86 | } 87 | 88 | WebRtcSocket socket; 89 | public string serverURL = "http://00000000.ngrok.io"; 90 | 91 | public void ConnectToServer() 92 | { 93 | //if (socket == null) 94 | { 95 | socket = new WebRtcSocket(); 96 | socket.OnOffer += (WebRtcMsg msg) => 97 | { 98 | status = "Offer received."; 99 | Debug.Log("SetRemoteDescription(offer) sdp:" + msg.msg); 100 | peer.SetRemoteDescription("offer", msg.msg); 101 | peer.CreateAnswer(); 102 | //socket.Emit("webrtc-answer", sdp); 103 | }; 104 | socket.OnAnswer += (WebRtcMsg msg) => 105 | { 106 | status = "Answer received."; 107 | //socket.Emit("webrtc-offer", sdp); 108 | Debug.Log("SetRemoteDescription(answer) sdp:"+ msg.msg); 109 | peer.SetRemoteDescription("answer", msg.msg); 110 | foreach(string candidate in iceCandidates) 111 | { 112 | socket.Emit("webrtc-icecandidate", candidate); 113 | } 114 | iceCandidates.Clear(); 115 | }; 116 | socket.OnJoin += (WebRtcMsg msg) => 117 | { 118 | status = "Joined"; 119 | }; 120 | socket.OnWelcome += (WebRtcMsg msg) => 121 | { 122 | if (this.offerSdp != null) 123 | { 124 | socket.Emit("webrtc-offer", offerSdp); 125 | } 126 | }; 127 | socket.OnExit += (WebRtcMsg msg) => 128 | { 129 | status = "Exited"; 130 | }; 131 | socket.OnConnect += () => 132 | { 133 | status = "Connected"; 134 | }; 135 | socket.OnConnectError += (msg) => 136 | { 137 | status = "Connect error: "+msg; 138 | }; 139 | socket.OnDisconnect += () => 140 | { 141 | status = "Disconnected"; 142 | }; 143 | status = "Connecting..."; 144 | socket.Open(serverURL); 145 | } 146 | } 147 | 148 | public void Close() 149 | { 150 | if (peer != null) 151 | { 152 | peer.ClosePeerConnection(); 153 | peer = null; 154 | } 155 | } 156 | 157 | public void OfferWithCamera() 158 | { 159 | Close(); 160 | InitWebRTC(); 161 | if (peer != null) 162 | { 163 | peer.AddStream(false); 164 | Debug.Log("calling peer.CreateOffer()"); 165 | peer.CreateOffer(); 166 | Debug.Log("called peer.CreateOffer()"); 167 | } 168 | } 169 | 170 | public void OfferWithoutCamera() 171 | { 172 | Close(); 173 | InitWebRTC(); 174 | if (peer != null) 175 | { 176 | Debug.Log("calling peer.CreateOffer()"); 177 | peer.CreateOffer(); 178 | Debug.Log("called peer.CreateOffer()"); 179 | } 180 | } 181 | 182 | // Update is called once per frame 183 | void Update() { 184 | } 185 | 186 | public void OnLocalSdpReadytoSend(int id, string type, string sdp) { 187 | Debug.Log("OnLocalSdpReadytoSend called. id="+id+" | type="+type+" | sdp="+sdp); 188 | // send offer 189 | 190 | if (type == "offer") 191 | { 192 | if (socket != null) 193 | { 194 | socket.Emit("webrtc-offer", sdp); 195 | status = "Offer sent."; 196 | } 197 | else 198 | { 199 | this.offerSdp = sdp; 200 | } 201 | } 202 | else if (type == "answer") 203 | { 204 | if (socket != null) 205 | { 206 | socket.Emit("webrtc-answer", sdp); 207 | status = "Answer sent."; 208 | } 209 | else 210 | { 211 | this.answerSdp = sdp; 212 | } 213 | } 214 | else 215 | { 216 | Debug.Log("Unknown type : " + type); 217 | } 218 | } 219 | 220 | public void OnIceCandiateReadytoSend(int id, string candidate, int sdpMlineIndex, string sdpMid) { 221 | Debug.Log("OnIceCandiateReadytoSend called. id="+id+" candidate="+candidate+" sdpMid="+sdpMid); 222 | if (socket != null) 223 | { 224 | socket.Emit("webrtc-icecandidate", candidate); 225 | } else 226 | { 227 | iceCandidates.Add(candidate); 228 | } 229 | } 230 | 231 | public void OnI420LocalFrameReady(int id, 232 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 233 | int strideY, int strideU, int strideV, int strideA, 234 | uint width, uint height) 235 | { 236 | 237 | //Debug.Log("OnI420LocalFrameReady called! w=" + width + " h=" + height+" thread:"+ Thread.CurrentThread.ManagedThreadId + ":" + Thread.CurrentThread.Name); 238 | FramePacket packet = frameQueueLocal.GetDataBufferWithoutContents((int) (width * height * 4)); 239 | if (packet == null) 240 | { 241 | //Debug.LogError("OnI420LocalFrameReady: FramePacket is null!"); 242 | return; 243 | } 244 | CopyYuvToBuffer(dataY, dataU, dataV, strideY, strideU, strideV, width, height, packet.Buffer); 245 | packet.width = (int)width; 246 | packet.height = (int)height; 247 | frameQueueLocal.Push(packet); 248 | } 249 | 250 | public void OnI420RemoteFrameReady(int id, 251 | IntPtr dataY, IntPtr dataU, IntPtr dataV, IntPtr dataA, 252 | int strideY, int strideU, int strideV, int strideA, 253 | uint width, uint height) 254 | { 255 | //Debug.Log("OnI420RemoteFrameReady called! w=" + width + " h=" + height + " thread:" + Thread.CurrentThread.ManagedThreadId); 256 | FramePacket packet = frameQueueRemote.GetDataBufferWithoutContents((int)(width * height * 4)); 257 | if (packet == null) 258 | { 259 | Debug.LogError("OnI420RemoteFrameReady: FramePacket is null!"); 260 | return; 261 | } 262 | CopyYuvToBuffer(dataY, dataU, dataV, strideY, strideU, strideV, width, height, packet.Buffer); 263 | packet.width = (int)width; 264 | packet.height = (int)height; 265 | frameQueueRemote.Push(packet); 266 | } 267 | 268 | void CopyYuvToBuffer(IntPtr dataY, IntPtr dataU, IntPtr dataV, 269 | int strideY, int strideU, int strideV, 270 | uint width, uint height, byte[] buffer) 271 | { 272 | unsafe 273 | { 274 | byte* ptrY = (byte*)dataY.ToPointer(); 275 | byte* ptrU = (byte*)dataU.ToPointer(); 276 | byte* ptrV = (byte*)dataV.ToPointer(); 277 | int srcOffsetY = 0; 278 | int srcOffsetU = 0; 279 | int srcOffsetV = 0; 280 | int destOffset = 0; 281 | for (int i = 0; i < height ; i++) 282 | { 283 | srcOffsetY = i * strideY; 284 | srcOffsetU = (i/2) * strideU; 285 | srcOffsetV = (i/2) * strideV; 286 | destOffset = i * (int)width * 4; 287 | for (int j = 0; j < width ; j+=2) 288 | { 289 | { 290 | byte y = ptrY[srcOffsetY]; 291 | byte u = ptrU[srcOffsetU]; 292 | byte v = ptrV[srcOffsetV]; 293 | srcOffsetY++; 294 | srcOffsetU++; 295 | srcOffsetV++; 296 | destOffset += 4; 297 | buffer[destOffset] = y; 298 | buffer[destOffset + 1] = u; 299 | buffer[destOffset + 2] = v; 300 | buffer[destOffset + 3] = 0xff; 301 | 302 | // use same u, v values 303 | byte y2 = ptrY[srcOffsetY]; 304 | srcOffsetY++; 305 | destOffset += 4; 306 | buffer[destOffset] = y2; 307 | buffer[destOffset + 1] = u; 308 | buffer[destOffset + 2] = v; 309 | buffer[destOffset + 3] = 0xff; 310 | } 311 | } 312 | } 313 | } 314 | } 315 | 316 | public void OnFailureMessage(int id, string msg) 317 | { 318 | Debug.Log("OnFailureMessage called! id=" + id + " msg=" + msg); 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcNativeCallSample.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 727e441c9cdde2a49bb7f5a861cce5e0 3 | timeCreated: 1518628276 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcSocket.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Quobject.SocketIoClientDotNet.Client; 5 | using Newtonsoft.Json; 6 | using System.Net.Security; 7 | using System.Security.Cryptography.X509Certificates; 8 | using Quobject.Collections.Immutable; 9 | 10 | public class WebRtcMsg 11 | { 12 | public int id; 13 | public string msg; 14 | }; 15 | 16 | public class WebRtcSocket 17 | { 18 | int myUserId = 0; 19 | Socket socket; 20 | 21 | public int MyUserId 22 | { 23 | get { return myUserId; } 24 | } 25 | 26 | public WebRtcSocket() 27 | { 28 | } 29 | 30 | public void Open(string url) 31 | { 32 | Debug.Log("SocketIO: connecting to:" + url); 33 | IO.Options opts = new IO.Options(); 34 | opts.Transports = ImmutableList.Empty.Add("polling"); 35 | Socket socket = IO.Socket(url, opts); 36 | 37 | socket.On(Socket.EVENT_CONNECT, () => 38 | { 39 | Debug.Log("SocketIO: connected!"); 40 | this.socket = socket; 41 | InitHandlers(); 42 | this.OnConnect(); 43 | }); 44 | socket.On(Socket.EVENT_CONNECT_ERROR, (msg) => 45 | { 46 | Debug.Log("SocketIO: connect error!"); 47 | this.OnConnectError("error:"+msg); 48 | }); 49 | socket.On(Socket.EVENT_DISCONNECT, () => 50 | { 51 | Debug.Log("SocketIO: disconnected!"); 52 | this.OnDisconnect(); 53 | this.socket = null; 54 | }); 55 | } 56 | 57 | void InitHandlers() 58 | { 59 | socket.On("welcome", (data) => 60 | { 61 | Debug.Log("SocketIO: welcome"); 62 | WebRtcMsg msg = ConvertDataToWebRtcMsg(data); 63 | myUserId = msg.id; 64 | this.OnWelcome(msg); 65 | }); 66 | socket.On("webrtc-offer", (data) => 67 | { 68 | WebRtcMsg msg = ConvertDataToWebRtcMsg(data); 69 | if (msg.id == myUserId) return; 70 | Debug.Log("SocketIO: webrtc-offer"); 71 | this.OnOffer(msg); 72 | }); 73 | socket.On("webrtc-answer", (data) => 74 | { 75 | WebRtcMsg msg = ConvertDataToWebRtcMsg(data); 76 | if (msg.id == myUserId) return; 77 | Debug.Log("SocketIO: webrtc-answer"); 78 | this.OnAnswer(msg); 79 | }); 80 | socket.On("join", (data) => 81 | { 82 | WebRtcMsg msg = ConvertDataToWebRtcMsg(data); 83 | if (msg.id == myUserId) return; 84 | Debug.Log("SocketIO: join"); 85 | this.OnJoin(msg); 86 | }); 87 | socket.On("exit", (data) => 88 | { 89 | WebRtcMsg msg = ConvertDataToWebRtcMsg(data); 90 | if (msg.id == myUserId) return; 91 | Debug.Log("SocketIO: exit"); 92 | this.OnExit(msg); 93 | }); 94 | } 95 | 96 | public void Emit(string msgType, string body) 97 | { 98 | Debug.Log("SocketIO: Emit msgType:" + msgType + " {id:" + myUserId + ", msg:" + body + "}"); 99 | this.socket.Emit(msgType, body); 100 | } 101 | 102 | WebRtcMsg ConvertDataToWebRtcMsg(object data) 103 | { 104 | string str = data.ToString(); 105 | WebRtcMsg msg = JsonConvert.DeserializeObject(str); 106 | //string strChatLog = "user#" + msg.id + ": " + msg.body; 107 | return msg; 108 | } 109 | 110 | public delegate void MessageListener(WebRtcMsg msg); 111 | public delegate void ConnectionListener(); 112 | public delegate void ErrorListener(string msg); 113 | 114 | public event MessageListener OnOffer; 115 | public event MessageListener OnAnswer; 116 | public event MessageListener OnJoin; 117 | public event MessageListener OnExit; 118 | public event MessageListener OnWelcome; 119 | public event ConnectionListener OnConnect; 120 | public event ErrorListener OnConnectError; 121 | public event ConnectionListener OnDisconnect; 122 | } -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcSocket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff072af23cb883b4ca82678336370bda 3 | timeCreated: 1521902551 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcVideoPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | public class WebRtcVideoPlayer : MonoBehaviour { 7 | 8 | private Texture2D tex; 9 | public FrameQueue frameQueue; // WebRtcNativeCallSampleがセットする。 10 | float lastUpdateTime; 11 | 12 | [SerializeField] 13 | private bool _playing; 14 | [SerializeField] 15 | private bool _failed; 16 | [SerializeField] 17 | private float _fpsLoad; 18 | [SerializeField] 19 | private float _fpsShow; 20 | [SerializeField] 21 | private float _fpsSkip; 22 | 23 | // Use this for initialization 24 | void Start () { 25 | tex = new Texture2D(2, 2); 26 | tex.SetPixel(0, 0, Color.blue); 27 | tex.SetPixel(1, 1, Color.blue); 28 | tex.Apply(); 29 | GetComponent().material.mainTexture = tex; 30 | } 31 | 32 | // Update is called once per frame 33 | void Update() 34 | { 35 | if (Time.fixedTime - lastUpdateTime > 1.0 / 31.0) 36 | { 37 | lastUpdateTime = Time.fixedTime; 38 | TryProcessFrame(); 39 | } 40 | 41 | if (frameQueue != null) { 42 | _fpsLoad = frameQueue.Stats.fpsLoad(); 43 | _fpsShow = frameQueue.Stats.fpsShow(); 44 | _fpsSkip = frameQueue.Stats.fpsSkip(); 45 | } 46 | } 47 | 48 | private void TryProcessFrame() 49 | { 50 | if (frameQueue != null) 51 | { 52 | FramePacket packet = frameQueue.Pop(); 53 | //Debug.Log((packet == null ? "no frame to consume." : "frame consumed.") + "framesCount : " + frameQueue.Count); 54 | if (packet != null) 55 | { 56 | ProcessFrameBuffer(packet); 57 | frameQueue.Pool(packet); 58 | } 59 | } 60 | } 61 | 62 | private void ProcessFrameBuffer(FramePacket packet) 63 | { 64 | if (packet == null) { 65 | return; 66 | } 67 | 68 | if (tex == null || (tex.width != packet.width || tex.height != packet.height)) { 69 | Debug.Log("Create Texture. width:"+packet.width+" height:"+packet.height); 70 | tex = new Texture2D(packet.width, packet.height, TextureFormat.RGBA32, false); 71 | } 72 | //Debug.Log("Received Packet. " + packet.ToString()); 73 | tex.LoadRawTextureData(packet.Buffer); 74 | 75 | tex.Apply(); 76 | GetComponent().material.mainTexture = tex; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/WebRtcVideoPlayer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc8fd41f51dd09c41972b00fc54c48e6 3 | timeCreated: 1520177866 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/WebRTCSample/main.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c621044344d27be4185399ec0a7713fd 3 | timeCreated: 1518272733 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_EnablePCM: 1 18 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 19 | m_AutoSimulation: 1 20 | m_AutoSyncTransforms: 1 21 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/main.unity 10 | guid: c621044344d27be4185399ec0a7713fd 11 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_ExternalVersionControlSupport: Hidden Meta Files 8 | m_SerializationMode: 2 9 | m_DefaultBehaviorMode: 0 10 | m_SpritePackerMode: 0 11 | m_SpritePackerPaddingPower: 1 12 | m_EtcTextureCompressorBehavior: 1 13 | m_EtcTextureFastCompressor: 1 14 | m_EtcTextureNormalCompressor: 2 15 | m_EtcTextureBestCompressor: 4 16 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 17 | m_ProjectGenerationRootNamespace: 18 | m_UserGeneratedProjectSuffix: 19 | m_CollabEditorSettings: 20 | inProgressEnabled: 1 21 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0} 40 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 41 | m_PreloadedShaders: [] 42 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 43 | type: 0} 44 | m_CustomRenderPipeline: {fileID: 0} 45 | m_TransparencySortMode: 0 46 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 47 | m_DefaultRenderingPath: 1 48 | m_DefaultMobileRenderingPath: 1 49 | m_TierSettings: [] 50 | m_LightmapStripping: 0 51 | m_FogStripping: 0 52 | m_InstancingStripping: 0 53 | m_LightmapKeepPlain: 1 54 | m_LightmapKeepDirCombined: 1 55 | m_LightmapKeepDynamicPlain: 1 56 | m_LightmapKeepDynamicDirCombined: 1 57 | m_LightmapKeepShadowMask: 1 58 | m_LightmapKeepSubtractive: 1 59 | m_FogKeepLinear: 1 60 | m_FogKeepExp: 1 61 | m_FogKeepExp2: 1 62 | m_AlbedoSwatchInfos: [] 63 | m_LightsUseLinearIntensity: 0 64 | m_LightsUseColorTemperature: 0 65 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_AutoSyncTransforms: 1 28 | m_AlwaysShowColliders: 0 29 | m_ShowColliderSleep: 1 30 | m_ShowColliderContacts: 0 31 | m_ShowColliderAABB: 0 32 | m_ContactArrowScale: 0.2 33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 38 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 14 7 | productGUID: 604f8122d740a2845bdd777bd92beba2 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | defaultScreenOrientation: 4 11 | targetDevice: 2 12 | useOnDemandResources: 0 13 | accelerometerFrequency: 60 14 | companyName: DefaultCompany 15 | productName: WebRTCSample 16 | defaultCursor: {fileID: 0} 17 | cursorHotspot: {x: 0, y: 0} 18 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 19 | m_ShowUnitySplashScreen: 1 20 | m_ShowUnitySplashLogo: 1 21 | m_SplashScreenOverlayOpacity: 1 22 | m_SplashScreenAnimation: 1 23 | m_SplashScreenLogoStyle: 1 24 | m_SplashScreenDrawMode: 0 25 | m_SplashScreenBackgroundAnimationZoom: 1 26 | m_SplashScreenLogoAnimationZoom: 1 27 | m_SplashScreenBackgroundLandscapeAspect: 1 28 | m_SplashScreenBackgroundPortraitAspect: 1 29 | m_SplashScreenBackgroundLandscapeUvs: 30 | serializedVersion: 2 31 | x: 0 32 | y: 0 33 | width: 1 34 | height: 1 35 | m_SplashScreenBackgroundPortraitUvs: 36 | serializedVersion: 2 37 | x: 0 38 | y: 0 39 | width: 1 40 | height: 1 41 | m_SplashScreenLogos: [] 42 | m_VirtualRealitySplashScreen: {fileID: 0} 43 | m_HolographicTrackingLossScreen: {fileID: 0} 44 | defaultScreenWidth: 1024 45 | defaultScreenHeight: 768 46 | defaultScreenWidthWeb: 960 47 | defaultScreenHeightWeb: 600 48 | m_StereoRenderingPath: 0 49 | m_ActiveColorSpace: 0 50 | m_MTRendering: 1 51 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 52 | iosShowActivityIndicatorOnLoading: -1 53 | androidShowActivityIndicatorOnLoading: -1 54 | tizenShowActivityIndicatorOnLoading: -1 55 | iosAppInBackgroundBehavior: 0 56 | displayResolutionDialog: 1 57 | iosAllowHTTPDownload: 1 58 | allowedAutorotateToPortrait: 1 59 | allowedAutorotateToPortraitUpsideDown: 1 60 | allowedAutorotateToLandscapeRight: 1 61 | allowedAutorotateToLandscapeLeft: 1 62 | useOSAutorotation: 1 63 | use32BitDisplayBuffer: 1 64 | preserveFramebufferAlpha: 0 65 | disableDepthAndStencilBuffers: 0 66 | androidBlitType: 0 67 | defaultIsFullScreen: 1 68 | defaultIsNativeResolution: 1 69 | macRetinaSupport: 1 70 | runInBackground: 0 71 | captureSingleScreen: 0 72 | muteOtherAudioSources: 0 73 | Prepare IOS For Recording: 0 74 | Force IOS Speakers When Recording: 0 75 | deferSystemGesturesMode: 0 76 | hideHomeButton: 0 77 | submitAnalytics: 1 78 | usePlayerLog: 1 79 | bakeCollisionMeshes: 0 80 | forceSingleInstance: 0 81 | resizableWindow: 0 82 | useMacAppStoreValidation: 0 83 | macAppStoreCategory: public.app-category.games 84 | gpuSkinning: 0 85 | graphicsJobs: 0 86 | xboxPIXTextureCapture: 0 87 | xboxEnableAvatar: 0 88 | xboxEnableKinect: 0 89 | xboxEnableKinectAutoTracking: 0 90 | xboxEnableFitness: 0 91 | visibleInBackground: 1 92 | allowFullscreenSwitch: 1 93 | graphicsJobMode: 0 94 | macFullscreenMode: 2 95 | d3d11FullscreenMode: 1 96 | xboxSpeechDB: 0 97 | xboxEnableHeadOrientation: 0 98 | xboxEnableGuest: 0 99 | xboxEnablePIXSampling: 0 100 | metalFramebufferOnly: 0 101 | n3dsDisableStereoscopicView: 0 102 | n3dsEnableSharedListOpt: 1 103 | n3dsEnableVSync: 0 104 | xboxOneResolution: 0 105 | xboxOneSResolution: 0 106 | xboxOneXResolution: 3 107 | xboxOneMonoLoggingLevel: 0 108 | xboxOneLoggingLevel: 1 109 | xboxOneDisableEsram: 0 110 | xboxOnePresentImmediateThreshold: 0 111 | videoMemoryForVertexBuffers: 0 112 | psp2PowerMode: 0 113 | psp2AcquireBGM: 1 114 | wiiUTVResolution: 0 115 | wiiUGamePadMSAA: 1 116 | wiiUSupportsNunchuk: 0 117 | wiiUSupportsClassicController: 0 118 | wiiUSupportsBalanceBoard: 0 119 | wiiUSupportsMotionPlus: 0 120 | wiiUSupportsProController: 0 121 | wiiUAllowScreenCapture: 1 122 | wiiUControllerCount: 0 123 | m_SupportedAspectRatios: 124 | 4:3: 1 125 | 5:4: 1 126 | 16:10: 1 127 | 16:9: 1 128 | Others: 1 129 | bundleVersion: 1.0 130 | preloadedAssets: [] 131 | metroInputSource: 0 132 | wsaTransparentSwapchain: 0 133 | m_HolographicPauseOnTrackingLoss: 1 134 | xboxOneDisableKinectGpuReservation: 0 135 | xboxOneEnable7thCore: 0 136 | vrSettings: 137 | cardboard: 138 | depthFormat: 0 139 | enableTransitionView: 0 140 | daydream: 141 | depthFormat: 0 142 | useSustainedPerformanceMode: 0 143 | enableVideoLayer: 0 144 | useProtectedVideoMemory: 0 145 | minimumSupportedHeadTracking: 0 146 | maximumSupportedHeadTracking: 1 147 | hololens: 148 | depthFormat: 1 149 | depthBufferSharingEnabled: 0 150 | oculus: 151 | sharedDepthBuffer: 0 152 | dashSupport: 0 153 | protectGraphicsMemory: 0 154 | useHDRDisplay: 0 155 | m_ColorGamuts: 00000000 156 | targetPixelDensity: 30 157 | resolutionScalingMode: 0 158 | androidSupportedAspectRatio: 1 159 | androidMaxAspectRatio: 2.1 160 | applicationIdentifier: 161 | Android: com.hammmm.WebRtcDllSample 162 | buildNumber: {} 163 | AndroidBundleVersionCode: 1 164 | AndroidMinSdkVersion: 24 165 | AndroidTargetSdkVersion: 0 166 | AndroidPreferredInstallLocation: 1 167 | aotOptions: 168 | stripEngineCode: 1 169 | iPhoneStrippingLevel: 0 170 | iPhoneScriptCallOptimization: 0 171 | ForceInternetPermission: 0 172 | ForceSDCardPermission: 0 173 | CreateWallpaper: 0 174 | APKExpansionFiles: 0 175 | keepLoadedShadersAlive: 0 176 | StripUnusedMeshComponents: 0 177 | VertexChannelCompressionMask: 178 | serializedVersion: 2 179 | m_Bits: 238 180 | iPhoneSdkVersion: 988 181 | iOSTargetOSVersionString: 7.0 182 | tvOSSdkVersion: 0 183 | tvOSRequireExtendedGameController: 0 184 | tvOSTargetOSVersionString: 9.0 185 | uIPrerenderedIcon: 0 186 | uIRequiresPersistentWiFi: 0 187 | uIRequiresFullScreen: 1 188 | uIStatusBarHidden: 1 189 | uIExitOnSuspend: 0 190 | uIStatusBarStyle: 0 191 | iPhoneSplashScreen: {fileID: 0} 192 | iPhoneHighResSplashScreen: {fileID: 0} 193 | iPhoneTallHighResSplashScreen: {fileID: 0} 194 | iPhone47inSplashScreen: {fileID: 0} 195 | iPhone55inPortraitSplashScreen: {fileID: 0} 196 | iPhone55inLandscapeSplashScreen: {fileID: 0} 197 | iPhone58inPortraitSplashScreen: {fileID: 0} 198 | iPhone58inLandscapeSplashScreen: {fileID: 0} 199 | iPadPortraitSplashScreen: {fileID: 0} 200 | iPadHighResPortraitSplashScreen: {fileID: 0} 201 | iPadLandscapeSplashScreen: {fileID: 0} 202 | iPadHighResLandscapeSplashScreen: {fileID: 0} 203 | appleTVSplashScreen: {fileID: 0} 204 | appleTVSplashScreen2x: {fileID: 0} 205 | tvOSSmallIconLayers: [] 206 | tvOSSmallIconLayers2x: [] 207 | tvOSLargeIconLayers: [] 208 | tvOSTopShelfImageLayers: [] 209 | tvOSTopShelfImageLayers2x: [] 210 | tvOSTopShelfImageWideLayers: [] 211 | tvOSTopShelfImageWideLayers2x: [] 212 | iOSLaunchScreenType: 0 213 | iOSLaunchScreenPortrait: {fileID: 0} 214 | iOSLaunchScreenLandscape: {fileID: 0} 215 | iOSLaunchScreenBackgroundColor: 216 | serializedVersion: 2 217 | rgba: 0 218 | iOSLaunchScreenFillPct: 100 219 | iOSLaunchScreenSize: 100 220 | iOSLaunchScreenCustomXibPath: 221 | iOSLaunchScreeniPadType: 0 222 | iOSLaunchScreeniPadImage: {fileID: 0} 223 | iOSLaunchScreeniPadBackgroundColor: 224 | serializedVersion: 2 225 | rgba: 0 226 | iOSLaunchScreeniPadFillPct: 100 227 | iOSLaunchScreeniPadSize: 100 228 | iOSLaunchScreeniPadCustomXibPath: 229 | iOSUseLaunchScreenStoryboard: 0 230 | iOSLaunchScreenCustomStoryboardPath: 231 | iOSDeviceRequirements: [] 232 | iOSURLSchemes: [] 233 | iOSBackgroundModes: 0 234 | iOSMetalForceHardShadows: 0 235 | metalEditorSupport: 1 236 | metalAPIValidation: 1 237 | iOSRenderExtraFrameOnPause: 0 238 | appleDeveloperTeamID: 239 | iOSManualSigningProvisioningProfileID: 240 | tvOSManualSigningProvisioningProfileID: 241 | appleEnableAutomaticSigning: 0 242 | clonedFromGUID: 00000000000000000000000000000000 243 | AndroidTargetDevice: 0 244 | AndroidSplashScreenScale: 0 245 | androidSplashScreen: {fileID: 0} 246 | AndroidKeystoreName: 247 | AndroidKeyaliasName: 248 | AndroidTVCompatibility: 1 249 | AndroidIsGame: 1 250 | AndroidEnableTango: 0 251 | androidEnableBanner: 1 252 | androidUseLowAccuracyLocation: 0 253 | m_AndroidBanners: 254 | - width: 320 255 | height: 180 256 | banner: {fileID: 0} 257 | androidGamepadSupportLevel: 0 258 | resolutionDialogBanner: {fileID: 0} 259 | m_BuildTargetIcons: [] 260 | m_BuildTargetBatching: [] 261 | m_BuildTargetGraphicsAPIs: 262 | - m_BuildTarget: AndroidPlayer 263 | m_APIs: 08000000 264 | m_Automatic: 0 265 | m_BuildTargetVRSettings: [] 266 | m_BuildTargetEnableVuforiaSettings: [] 267 | openGLRequireES31: 0 268 | openGLRequireES31AEP: 0 269 | m_TemplateCustomTags: {} 270 | mobileMTRendering: 271 | Android: 1 272 | iPhone: 1 273 | tvOS: 1 274 | m_BuildTargetGroupLightmapEncodingQuality: 275 | - m_BuildTarget: Standalone 276 | m_EncodingQuality: 1 277 | - m_BuildTarget: XboxOne 278 | m_EncodingQuality: 1 279 | - m_BuildTarget: PS4 280 | m_EncodingQuality: 1 281 | wiiUTitleID: 0005000011000000 282 | wiiUGroupID: 00010000 283 | wiiUCommonSaveSize: 4096 284 | wiiUAccountSaveSize: 2048 285 | wiiUOlvAccessKey: 0 286 | wiiUTinCode: 0 287 | wiiUJoinGameId: 0 288 | wiiUJoinGameModeMask: 0000000000000000 289 | wiiUCommonBossSize: 0 290 | wiiUAccountBossSize: 0 291 | wiiUAddOnUniqueIDs: [] 292 | wiiUMainThreadStackSize: 3072 293 | wiiULoaderThreadStackSize: 1024 294 | wiiUSystemHeapSize: 128 295 | wiiUTVStartupScreen: {fileID: 0} 296 | wiiUGamePadStartupScreen: {fileID: 0} 297 | wiiUDrcBufferDisabled: 0 298 | wiiUProfilerLibPath: 299 | playModeTestRunnerEnabled: 0 300 | actionOnDotNetUnhandledException: 1 301 | enableInternalProfiler: 0 302 | logObjCUncaughtExceptions: 1 303 | enableCrashReportAPI: 0 304 | cameraUsageDescription: 305 | locationUsageDescription: 306 | microphoneUsageDescription: 307 | switchNetLibKey: 308 | switchSocketMemoryPoolSize: 6144 309 | switchSocketAllocatorPoolSize: 128 310 | switchSocketConcurrencyLimit: 14 311 | switchScreenResolutionBehavior: 2 312 | switchUseCPUProfiler: 0 313 | switchApplicationID: 0x01004b9000490000 314 | switchNSODependencies: 315 | switchTitleNames_0: 316 | switchTitleNames_1: 317 | switchTitleNames_2: 318 | switchTitleNames_3: 319 | switchTitleNames_4: 320 | switchTitleNames_5: 321 | switchTitleNames_6: 322 | switchTitleNames_7: 323 | switchTitleNames_8: 324 | switchTitleNames_9: 325 | switchTitleNames_10: 326 | switchTitleNames_11: 327 | switchTitleNames_12: 328 | switchTitleNames_13: 329 | switchTitleNames_14: 330 | switchPublisherNames_0: 331 | switchPublisherNames_1: 332 | switchPublisherNames_2: 333 | switchPublisherNames_3: 334 | switchPublisherNames_4: 335 | switchPublisherNames_5: 336 | switchPublisherNames_6: 337 | switchPublisherNames_7: 338 | switchPublisherNames_8: 339 | switchPublisherNames_9: 340 | switchPublisherNames_10: 341 | switchPublisherNames_11: 342 | switchPublisherNames_12: 343 | switchPublisherNames_13: 344 | switchPublisherNames_14: 345 | switchIcons_0: {fileID: 0} 346 | switchIcons_1: {fileID: 0} 347 | switchIcons_2: {fileID: 0} 348 | switchIcons_3: {fileID: 0} 349 | switchIcons_4: {fileID: 0} 350 | switchIcons_5: {fileID: 0} 351 | switchIcons_6: {fileID: 0} 352 | switchIcons_7: {fileID: 0} 353 | switchIcons_8: {fileID: 0} 354 | switchIcons_9: {fileID: 0} 355 | switchIcons_10: {fileID: 0} 356 | switchIcons_11: {fileID: 0} 357 | switchIcons_12: {fileID: 0} 358 | switchIcons_13: {fileID: 0} 359 | switchIcons_14: {fileID: 0} 360 | switchSmallIcons_0: {fileID: 0} 361 | switchSmallIcons_1: {fileID: 0} 362 | switchSmallIcons_2: {fileID: 0} 363 | switchSmallIcons_3: {fileID: 0} 364 | switchSmallIcons_4: {fileID: 0} 365 | switchSmallIcons_5: {fileID: 0} 366 | switchSmallIcons_6: {fileID: 0} 367 | switchSmallIcons_7: {fileID: 0} 368 | switchSmallIcons_8: {fileID: 0} 369 | switchSmallIcons_9: {fileID: 0} 370 | switchSmallIcons_10: {fileID: 0} 371 | switchSmallIcons_11: {fileID: 0} 372 | switchSmallIcons_12: {fileID: 0} 373 | switchSmallIcons_13: {fileID: 0} 374 | switchSmallIcons_14: {fileID: 0} 375 | switchManualHTML: 376 | switchAccessibleURLs: 377 | switchLegalInformation: 378 | switchMainThreadStackSize: 1048576 379 | switchPresenceGroupId: 380 | switchLogoHandling: 0 381 | switchReleaseVersion: 0 382 | switchDisplayVersion: 1.0.0 383 | switchStartupUserAccount: 0 384 | switchTouchScreenUsage: 0 385 | switchSupportedLanguagesMask: 0 386 | switchLogoType: 0 387 | switchApplicationErrorCodeCategory: 388 | switchUserAccountSaveDataSize: 0 389 | switchUserAccountSaveDataJournalSize: 0 390 | switchApplicationAttribute: 0 391 | switchCardSpecSize: -1 392 | switchCardSpecClock: -1 393 | switchRatingsMask: 0 394 | switchRatingsInt_0: 0 395 | switchRatingsInt_1: 0 396 | switchRatingsInt_2: 0 397 | switchRatingsInt_3: 0 398 | switchRatingsInt_4: 0 399 | switchRatingsInt_5: 0 400 | switchRatingsInt_6: 0 401 | switchRatingsInt_7: 0 402 | switchRatingsInt_8: 0 403 | switchRatingsInt_9: 0 404 | switchRatingsInt_10: 0 405 | switchRatingsInt_11: 0 406 | switchLocalCommunicationIds_0: 407 | switchLocalCommunicationIds_1: 408 | switchLocalCommunicationIds_2: 409 | switchLocalCommunicationIds_3: 410 | switchLocalCommunicationIds_4: 411 | switchLocalCommunicationIds_5: 412 | switchLocalCommunicationIds_6: 413 | switchLocalCommunicationIds_7: 414 | switchParentalControl: 0 415 | switchAllowsScreenshot: 1 416 | switchAllowsVideoCapturing: 1 417 | switchAllowsRuntimeAddOnContentInstall: 0 418 | switchDataLossConfirmation: 0 419 | switchSupportedNpadStyles: 3 420 | switchSocketConfigEnabled: 0 421 | switchTcpInitialSendBufferSize: 32 422 | switchTcpInitialReceiveBufferSize: 64 423 | switchTcpAutoSendBufferSizeMax: 256 424 | switchTcpAutoReceiveBufferSizeMax: 256 425 | switchUdpSendBufferSize: 9 426 | switchUdpReceiveBufferSize: 42 427 | switchSocketBufferEfficiency: 4 428 | switchSocketInitializeEnabled: 1 429 | switchNetworkInterfaceManagerInitializeEnabled: 1 430 | switchPlayerConnectionEnabled: 1 431 | ps4NPAgeRating: 12 432 | ps4NPTitleSecret: 433 | ps4NPTrophyPackPath: 434 | ps4ParentalLevel: 11 435 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 436 | ps4Category: 0 437 | ps4MasterVersion: 01.00 438 | ps4AppVersion: 01.00 439 | ps4AppType: 0 440 | ps4ParamSfxPath: 441 | ps4VideoOutPixelFormat: 0 442 | ps4VideoOutInitialWidth: 1920 443 | ps4VideoOutBaseModeInitialWidth: 1920 444 | ps4VideoOutReprojectionRate: 60 445 | ps4PronunciationXMLPath: 446 | ps4PronunciationSIGPath: 447 | ps4BackgroundImagePath: 448 | ps4StartupImagePath: 449 | ps4StartupImagesFolder: 450 | ps4IconImagesFolder: 451 | ps4SaveDataImagePath: 452 | ps4SdkOverride: 453 | ps4BGMPath: 454 | ps4ShareFilePath: 455 | ps4ShareOverlayImagePath: 456 | ps4PrivacyGuardImagePath: 457 | ps4NPtitleDatPath: 458 | ps4RemotePlayKeyAssignment: -1 459 | ps4RemotePlayKeyMappingDir: 460 | ps4PlayTogetherPlayerCount: 0 461 | ps4EnterButtonAssignment: 1 462 | ps4ApplicationParam1: 0 463 | ps4ApplicationParam2: 0 464 | ps4ApplicationParam3: 0 465 | ps4ApplicationParam4: 0 466 | ps4DownloadDataSize: 0 467 | ps4GarlicHeapSize: 2048 468 | ps4ProGarlicHeapSize: 2560 469 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 470 | ps4pnSessions: 1 471 | ps4pnPresence: 1 472 | ps4pnFriends: 1 473 | ps4pnGameCustomData: 1 474 | playerPrefsSupport: 0 475 | restrictedAudioUsageRights: 0 476 | ps4UseResolutionFallback: 0 477 | ps4ReprojectionSupport: 0 478 | ps4UseAudio3dBackend: 0 479 | ps4SocialScreenEnabled: 0 480 | ps4ScriptOptimizationLevel: 0 481 | ps4Audio3dVirtualSpeakerCount: 14 482 | ps4attribCpuUsage: 0 483 | ps4PatchPkgPath: 484 | ps4PatchLatestPkgPath: 485 | ps4PatchChangeinfoPath: 486 | ps4PatchDayOne: 0 487 | ps4attribUserManagement: 0 488 | ps4attribMoveSupport: 0 489 | ps4attrib3DSupport: 0 490 | ps4attribShareSupport: 0 491 | ps4attribExclusiveVR: 0 492 | ps4disableAutoHideSplash: 0 493 | ps4videoRecordingFeaturesUsed: 0 494 | ps4contentSearchFeaturesUsed: 0 495 | ps4attribEyeToEyeDistanceSettingVR: 0 496 | ps4IncludedModules: [] 497 | monoEnv: 498 | psp2Splashimage: {fileID: 0} 499 | psp2NPTrophyPackPath: 500 | psp2NPSupportGBMorGJP: 0 501 | psp2NPAgeRating: 12 502 | psp2NPTitleDatPath: 503 | psp2NPCommsID: 504 | psp2NPCommunicationsID: 505 | psp2NPCommsPassphrase: 506 | psp2NPCommsSig: 507 | psp2ParamSfxPath: 508 | psp2ManualPath: 509 | psp2LiveAreaGatePath: 510 | psp2LiveAreaBackroundPath: 511 | psp2LiveAreaPath: 512 | psp2LiveAreaTrialPath: 513 | psp2PatchChangeInfoPath: 514 | psp2PatchOriginalPackage: 515 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui 516 | psp2KeystoneFile: 517 | psp2MemoryExpansionMode: 0 518 | psp2DRMType: 0 519 | psp2StorageType: 0 520 | psp2MediaCapacity: 0 521 | psp2DLCConfigPath: 522 | psp2ThumbnailPath: 523 | psp2BackgroundPath: 524 | psp2SoundPath: 525 | psp2TrophyCommId: 526 | psp2TrophyPackagePath: 527 | psp2PackagedResourcesPath: 528 | psp2SaveDataQuota: 10240 529 | psp2ParentalLevel: 1 530 | psp2ShortTitle: Not Set 531 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 532 | psp2Category: 0 533 | psp2MasterVersion: 01.00 534 | psp2AppVersion: 01.00 535 | psp2TVBootMode: 0 536 | psp2EnterButtonAssignment: 2 537 | psp2TVDisableEmu: 0 538 | psp2AllowTwitterDialog: 1 539 | psp2Upgradable: 0 540 | psp2HealthWarning: 0 541 | psp2UseLibLocation: 0 542 | psp2InfoBarOnStartup: 0 543 | psp2InfoBarColor: 0 544 | psp2ScriptOptimizationLevel: 0 545 | psmSplashimage: {fileID: 0} 546 | splashScreenBackgroundSourceLandscape: {fileID: 0} 547 | splashScreenBackgroundSourcePortrait: {fileID: 0} 548 | spritePackerPolicy: 549 | webGLMemorySize: 256 550 | webGLExceptionSupport: 1 551 | webGLNameFilesAsHashes: 0 552 | webGLDataCaching: 0 553 | webGLDebugSymbols: 0 554 | webGLEmscriptenArgs: 555 | webGLModulesDirectory: 556 | webGLTemplate: APPLICATION:Default 557 | webGLAnalyzeBuildSize: 0 558 | webGLUseEmbeddedResources: 0 559 | webGLUseWasm: 0 560 | webGLCompressionFormat: 1 561 | scriptingDefineSymbols: {} 562 | platformArchitecture: {} 563 | scriptingBackend: {} 564 | incrementalIl2cppBuild: {} 565 | additionalIl2CppArgs: 566 | scriptingRuntimeVersion: 0 567 | apiCompatibilityLevelPerPlatform: 568 | Android: 1 569 | m_RenderingPath: 1 570 | m_MobileRenderingPath: 1 571 | metroPackageName: NewAndroidUnityProject 572 | metroPackageVersion: 573 | metroCertificatePath: 574 | metroCertificatePassword: 575 | metroCertificateSubject: 576 | metroCertificateIssuer: 577 | metroCertificateNotAfter: 0000000000000000 578 | metroApplicationDescription: NewAndroidUnityProject 579 | wsaImages: {} 580 | metroTileShortName: 581 | metroCommandLineArgsFile: 582 | metroTileShowName: 0 583 | metroMediumTileShowName: 0 584 | metroLargeTileShowName: 0 585 | metroWideTileShowName: 0 586 | metroDefaultTileSize: 1 587 | metroTileForegroundText: 2 588 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 589 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 590 | a: 1} 591 | metroSplashScreenUseBackgroundColor: 0 592 | platformCapabilities: {} 593 | metroFTAName: 594 | metroFTAFileTypes: [] 595 | metroProtocolName: 596 | metroCompilationOverrides: 1 597 | tizenProductDescription: 598 | tizenProductURL: 599 | tizenSigningProfileName: 600 | tizenGPSPermissions: 0 601 | tizenMicrophonePermissions: 0 602 | tizenDeploymentTarget: 603 | tizenDeploymentTargetType: -1 604 | tizenMinOSVersion: 1 605 | n3dsUseExtSaveData: 0 606 | n3dsCompressStaticMem: 1 607 | n3dsExtSaveDataNumber: 0x12345 608 | n3dsStackSize: 131072 609 | n3dsTargetPlatform: 2 610 | n3dsRegion: 7 611 | n3dsMediaSize: 0 612 | n3dsLogoStyle: 3 613 | n3dsTitle: GameName 614 | n3dsProductCode: 615 | n3dsApplicationId: 0xFF3FF 616 | XboxOneProductId: 617 | XboxOneUpdateKey: 618 | XboxOneSandboxId: 619 | XboxOneContentId: 620 | XboxOneTitleId: 621 | XboxOneSCId: 622 | XboxOneGameOsOverridePath: 623 | XboxOnePackagingOverridePath: 624 | XboxOneAppManifestOverridePath: 625 | XboxOnePackageEncryption: 0 626 | XboxOnePackageUpdateGranularity: 2 627 | XboxOneDescription: 628 | XboxOneLanguage: 629 | - enus 630 | XboxOneCapability: [] 631 | XboxOneGameRating: {} 632 | XboxOneIsContentPackage: 0 633 | XboxOneEnableGPUVariability: 0 634 | XboxOneSockets: {} 635 | XboxOneSplashScreen: {fileID: 0} 636 | XboxOneAllowedProductIds: [] 637 | XboxOnePersistentLocalStorageSize: 0 638 | xboxOneScriptCompiler: 0 639 | vrEditorSettings: 640 | daydream: 641 | daydreamIconForeground: {fileID: 0} 642 | daydreamIconBackground: {fileID: 0} 643 | cloudServicesEnabled: {} 644 | facebookSdkVersion: 7.9.4 645 | apiCompatibilityLevel: 2 646 | cloudProjectId: 647 | projectName: 648 | organizationId: 649 | cloudEnabled: 0 650 | enableNativePlatformBackendsForNewInputSystem: 0 651 | disableOldInputManagerSupport: 0 652 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.3.1f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 4 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 4 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 1 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 1 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 4 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 2 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 1 108 | antiAliasing: 0 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 1 112 | billboardsFaceCameraPosition: 1 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 4 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 2 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 70 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 2 136 | antiAliasing: 2 137 | softParticles: 1 138 | softVegetation: 1 139 | realtimeReflectionProbes: 1 140 | billboardsFaceCameraPosition: 1 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 4 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 4 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSM: 5 183 | PSP2: 2 184 | Samsung TV: 2 185 | Standalone: 5 186 | Tizen: 2 187 | WebGL: 3 188 | WiiU: 5 189 | Windows Store Apps: 5 190 | XboxOne: 5 191 | iPhone: 2 192 | tvOS: 2 193 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | m_TestInitMode: 0 11 | CrashReportingSettings: 12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate 14 | m_Enabled: 0 15 | m_CaptureEditorExceptions: 1 16 | UnityPurchasingSettings: 17 | m_Enabled: 0 18 | m_TestMode: 0 19 | UnityAnalyticsSettings: 20 | m_Enabled: 0 21 | m_InitializeOnStartup: 1 22 | m_TestMode: 0 23 | m_TestEventUrl: 24 | m_TestConfigUrl: 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Sample unity3d project to demonstrate WebRTC official unity plugin. 4 | with simple WebRTC signaling implemented with Socket.IO. 5 | 6 | # Requirements 7 | 8 | * Unity3D 2017.3+ 9 | * node.js 10 | 11 | # Using Libraries 12 | 13 | * WebRTC (official) unity plugin: https://github.com/mhama/webrtc-dev-env 14 | 15 | * `Socket.IO` library: https://github.com/floatinghotpot/socket.io-unity 16 | 17 | # Instructions 18 | 19 | ## launch signaling server 20 | 21 | * On Windows: 22 | 23 | ```sh 24 | > server.bat 25 | ``` 26 | or 27 | 28 | * On Mac/Linux 29 | 30 | ```sh 31 | npm install 32 | node index.js 33 | ``` 34 | 35 | * Output Log 36 | 37 | ``` 38 | >call npm install 39 | npm WARN webrtc-simple-signaling-server@0.0.1 No description 40 | npm WARN webrtc-simple-signaling-server@0.0.1 No repository field. 41 | ... 42 | 43 | listening on *:3000 44 | forwarding to global domain... 45 | ngrok server: https://440ab904.ngrok.io 46 | ``` 47 | 48 | * The last "ngrok server" part is IMPORTANT! 49 | * the server URL lasts for 24 hours only. After that, you need to restart server for another 24 hours. 50 | 51 | ## Launch unity app 52 | 53 | `build and run` unity project. 54 | 55 | ## Start WebRTC on unity app 56 | 57 | * set the above `ngrok server` URL to app's server URL field. (but use http:// rather than https://) 58 | * push `Connect` button 59 | * push `Offer with Camera` button 60 | 61 | ## Start the other side of WebRTC 62 | 63 | * browse the above `ngrok server` URL with web browser. (the web browser needs to support WebRTC). 64 | * push `Start Camera` button 65 | * push `Start Peer` button 66 | 67 | # Signaling 68 | 69 | This sample use signaling with http long polling of Socket.IO. 70 | Very dirty implementation that doesnot handle bad states or errors. 71 | 72 | # Caution 73 | 74 | Beware that WebRTC may use very much bandwidth! Beware especially if you are not using fixed price connection. 75 | -------------------------------------------------------------------------------- /UnityPackageManager/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /server/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Socket.IO chat 5 | 15 | 16 | 17 | 18 | 19 | 248 | 249 | 250 | 251 | 252 | 253 | 254 |
    255 |
    256 | 257 |
    258 | 259 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | var app = require('express')(); 2 | var http = require('http').Server(app); 3 | var io = require('socket.io')(http, { 4 | transports: ['polling'] 5 | }); 6 | const ngrok = require('ngrok'); 7 | 8 | app.get('/', function(req, res){ 9 | res.sendFile(__dirname + '/index.html'); 10 | }); 11 | 12 | // simple and dirty WebRTC signaling (without sending each ice candidates) 13 | // see: https://qiita.com/massie_g/items/f5baf316652bbc6fcef1 14 | var userId = 0; 15 | io.on('connection', function(socket){ 16 | socket.userId = userId ++; 17 | console.log('a user connected, user id: ' + socket.userId); 18 | socket.emit("welcome", { id: socket.userId }); 19 | io.emit("join", { id: socket.userId } ); 20 | 21 | socket.on('chat', function(msg){ 22 | console.log('message from user#' + socket.userId + ": " + msg); 23 | io.emit('chat', { 24 | id: socket.userId, 25 | msg: msg 26 | }); 27 | }); 28 | socket.on('webrtc-offer', function(msg){ 29 | console.log('webrtc-offer from user#' + socket.userId + ": " + msg); 30 | io.emit('webrtc-offer', { 31 | id: socket.userId, 32 | msg: msg 33 | }); 34 | }); 35 | socket.on('webrtc-answer', function(msg){ 36 | console.log('webrtc-answer from user#' + socket.userId + ": " + msg); 37 | io.emit('webrtc-answer', { 38 | id: socket.userId, 39 | msg: msg 40 | }); 41 | }); 42 | socket.on('webrtc-icecandidate', function(msg){ 43 | console.log('webrtc-icecandidate from user#' + socket.userId + ": " + msg); 44 | io.emit('webrtc-icecandidate', { 45 | id: socket.userId, 46 | msg: msg 47 | }); 48 | }); 49 | socket.on('disconnect', function() { 50 | io.emit("exit", { id: socket.userId }); 51 | }) 52 | }); 53 | 54 | const port = 3000; 55 | http.listen(port, function(){ 56 | console.log('listening on *:'+port); 57 | console.log('forwarding to global domain...') 58 | ngrok.connect(port, (err, url) => { 59 | console.log("ngrok server: "+url); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webrtc-simple-signaling-server", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "8.9.5", 9 | "resolved": "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz", 10 | "integrity": "sha512-jRHfWsvyMtXdbhnz5CVHxaBgnV6duZnPlQuRSo/dm/GnmikNcmZhxIES4E9OZjUmQ8C+HCl4KJux+cXN/ErGDQ==" 11 | }, 12 | "abbrev": { 13 | "version": "1.1.1", 14 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 15 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 16 | }, 17 | "accepts": { 18 | "version": "1.3.5", 19 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 20 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 21 | "requires": { 22 | "mime-types": "2.1.18", 23 | "negotiator": "0.6.1" 24 | } 25 | }, 26 | "after": { 27 | "version": "0.8.2", 28 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", 29 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" 30 | }, 31 | "ajv": { 32 | "version": "5.5.2", 33 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 34 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 35 | "requires": { 36 | "co": "4.6.0", 37 | "fast-deep-equal": "1.1.0", 38 | "fast-json-stable-stringify": "2.0.0", 39 | "json-schema-traverse": "0.3.1" 40 | } 41 | }, 42 | "array-flatten": { 43 | "version": "1.1.1", 44 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 45 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 46 | }, 47 | "arraybuffer.slice": { 48 | "version": "0.0.6", 49 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", 50 | "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=" 51 | }, 52 | "asn1": { 53 | "version": "0.2.3", 54 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 55 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" 56 | }, 57 | "assert-plus": { 58 | "version": "1.0.0", 59 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 60 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 61 | }, 62 | "async": { 63 | "version": "2.6.0", 64 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", 65 | "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", 66 | "requires": { 67 | "lodash": "4.17.5" 68 | } 69 | }, 70 | "asynckit": { 71 | "version": "0.4.0", 72 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 73 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 74 | }, 75 | "aws-sign2": { 76 | "version": "0.7.0", 77 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 78 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 79 | }, 80 | "aws4": { 81 | "version": "1.6.0", 82 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 83 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" 84 | }, 85 | "backo2": { 86 | "version": "1.0.2", 87 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", 88 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" 89 | }, 90 | "base64-arraybuffer": { 91 | "version": "0.1.5", 92 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", 93 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" 94 | }, 95 | "base64id": { 96 | "version": "1.0.0", 97 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", 98 | "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" 99 | }, 100 | "bcrypt-pbkdf": { 101 | "version": "1.0.1", 102 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 103 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 104 | "optional": true, 105 | "requires": { 106 | "tweetnacl": "0.14.5" 107 | } 108 | }, 109 | "better-assert": { 110 | "version": "1.0.2", 111 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", 112 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", 113 | "requires": { 114 | "callsite": "1.0.0" 115 | } 116 | }, 117 | "binary": { 118 | "version": "0.3.0", 119 | "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", 120 | "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", 121 | "requires": { 122 | "buffers": "0.1.1", 123 | "chainsaw": "0.1.0" 124 | } 125 | }, 126 | "blob": { 127 | "version": "0.0.4", 128 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", 129 | "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=" 130 | }, 131 | "body-parser": { 132 | "version": "1.18.2", 133 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 134 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 135 | "requires": { 136 | "bytes": "3.0.0", 137 | "content-type": "1.0.4", 138 | "debug": "2.6.9", 139 | "depd": "1.1.2", 140 | "http-errors": "1.6.2", 141 | "iconv-lite": "0.4.19", 142 | "on-finished": "2.3.0", 143 | "qs": "6.5.1", 144 | "raw-body": "2.3.2", 145 | "type-is": "1.6.16" 146 | } 147 | }, 148 | "boom": { 149 | "version": "4.3.1", 150 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", 151 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", 152 | "requires": { 153 | "hoek": "4.2.1" 154 | } 155 | }, 156 | "buffers": { 157 | "version": "0.1.1", 158 | "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", 159 | "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" 160 | }, 161 | "bytes": { 162 | "version": "3.0.0", 163 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 164 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 165 | }, 166 | "callsite": { 167 | "version": "1.0.0", 168 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", 169 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" 170 | }, 171 | "caseless": { 172 | "version": "0.12.0", 173 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 174 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 175 | }, 176 | "chainsaw": { 177 | "version": "0.1.0", 178 | "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", 179 | "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", 180 | "requires": { 181 | "traverse": "0.3.9" 182 | } 183 | }, 184 | "co": { 185 | "version": "4.6.0", 186 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 187 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 188 | }, 189 | "combined-stream": { 190 | "version": "1.0.6", 191 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 192 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 193 | "requires": { 194 | "delayed-stream": "1.0.0" 195 | } 196 | }, 197 | "component-bind": { 198 | "version": "1.0.0", 199 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", 200 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" 201 | }, 202 | "component-emitter": { 203 | "version": "1.1.2", 204 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", 205 | "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=" 206 | }, 207 | "component-inherit": { 208 | "version": "0.0.3", 209 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", 210 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" 211 | }, 212 | "content-disposition": { 213 | "version": "0.5.2", 214 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 215 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 216 | }, 217 | "content-type": { 218 | "version": "1.0.4", 219 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 220 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 221 | }, 222 | "cookie": { 223 | "version": "0.3.1", 224 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 225 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 226 | }, 227 | "cookie-signature": { 228 | "version": "1.0.6", 229 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 230 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 231 | }, 232 | "core-util-is": { 233 | "version": "1.0.2", 234 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 235 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 236 | }, 237 | "cryptiles": { 238 | "version": "3.1.2", 239 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", 240 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", 241 | "requires": { 242 | "boom": "5.2.0" 243 | }, 244 | "dependencies": { 245 | "boom": { 246 | "version": "5.2.0", 247 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", 248 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", 249 | "requires": { 250 | "hoek": "4.2.1" 251 | } 252 | } 253 | } 254 | }, 255 | "dashdash": { 256 | "version": "1.14.1", 257 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 258 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 259 | "requires": { 260 | "assert-plus": "1.0.0" 261 | } 262 | }, 263 | "debug": { 264 | "version": "2.6.9", 265 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 266 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 267 | "requires": { 268 | "ms": "2.0.0" 269 | } 270 | }, 271 | "decompress-zip": { 272 | "version": "0.3.0", 273 | "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", 274 | "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", 275 | "requires": { 276 | "binary": "0.3.0", 277 | "graceful-fs": "4.1.11", 278 | "mkpath": "0.1.0", 279 | "nopt": "3.0.6", 280 | "q": "1.5.1", 281 | "readable-stream": "1.1.14", 282 | "touch": "0.0.3" 283 | } 284 | }, 285 | "delayed-stream": { 286 | "version": "1.0.0", 287 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 288 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 289 | }, 290 | "depd": { 291 | "version": "1.1.2", 292 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 293 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 294 | }, 295 | "destroy": { 296 | "version": "1.0.4", 297 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 298 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 299 | }, 300 | "ecc-jsbn": { 301 | "version": "0.1.1", 302 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 303 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 304 | "optional": true, 305 | "requires": { 306 | "jsbn": "0.1.1" 307 | } 308 | }, 309 | "ee-first": { 310 | "version": "1.1.1", 311 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 312 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 313 | }, 314 | "encodeurl": { 315 | "version": "1.0.2", 316 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 317 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 318 | }, 319 | "engine.io": { 320 | "version": "1.8.5", 321 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.5.tgz", 322 | "integrity": "sha512-j1DWIcktw4hRwrv6nWx++5nFH2X64x16MAG2P0Lmi5Dvdfi3I+Jhc7JKJIdAmDJa+5aZ/imHV7dWRPy2Cqjh3A==", 323 | "requires": { 324 | "accepts": "1.3.3", 325 | "base64id": "1.0.0", 326 | "cookie": "0.3.1", 327 | "debug": "2.3.3", 328 | "engine.io-parser": "1.3.2", 329 | "ws": "1.1.5" 330 | }, 331 | "dependencies": { 332 | "accepts": { 333 | "version": "1.3.3", 334 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", 335 | "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", 336 | "requires": { 337 | "mime-types": "2.1.18", 338 | "negotiator": "0.6.1" 339 | } 340 | }, 341 | "debug": { 342 | "version": "2.3.3", 343 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", 344 | "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", 345 | "requires": { 346 | "ms": "0.7.2" 347 | } 348 | }, 349 | "ms": { 350 | "version": "0.7.2", 351 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", 352 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" 353 | } 354 | } 355 | }, 356 | "engine.io-client": { 357 | "version": "1.8.5", 358 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz", 359 | "integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==", 360 | "requires": { 361 | "component-emitter": "1.2.1", 362 | "component-inherit": "0.0.3", 363 | "debug": "2.3.3", 364 | "engine.io-parser": "1.3.2", 365 | "has-cors": "1.1.0", 366 | "indexof": "0.0.1", 367 | "parsejson": "0.0.3", 368 | "parseqs": "0.0.5", 369 | "parseuri": "0.0.5", 370 | "ws": "1.1.5", 371 | "xmlhttprequest-ssl": "1.5.3", 372 | "yeast": "0.1.2" 373 | }, 374 | "dependencies": { 375 | "component-emitter": { 376 | "version": "1.2.1", 377 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 378 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 379 | }, 380 | "debug": { 381 | "version": "2.3.3", 382 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", 383 | "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", 384 | "requires": { 385 | "ms": "0.7.2" 386 | } 387 | }, 388 | "ms": { 389 | "version": "0.7.2", 390 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", 391 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" 392 | } 393 | } 394 | }, 395 | "engine.io-parser": { 396 | "version": "1.3.2", 397 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", 398 | "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", 399 | "requires": { 400 | "after": "0.8.2", 401 | "arraybuffer.slice": "0.0.6", 402 | "base64-arraybuffer": "0.1.5", 403 | "blob": "0.0.4", 404 | "has-binary": "0.1.7", 405 | "wtf-8": "1.0.0" 406 | } 407 | }, 408 | "escape-html": { 409 | "version": "1.0.3", 410 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 411 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 412 | }, 413 | "etag": { 414 | "version": "1.8.1", 415 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 416 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 417 | }, 418 | "express": { 419 | "version": "4.16.3", 420 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", 421 | "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", 422 | "requires": { 423 | "accepts": "1.3.5", 424 | "array-flatten": "1.1.1", 425 | "body-parser": "1.18.2", 426 | "content-disposition": "0.5.2", 427 | "content-type": "1.0.4", 428 | "cookie": "0.3.1", 429 | "cookie-signature": "1.0.6", 430 | "debug": "2.6.9", 431 | "depd": "1.1.2", 432 | "encodeurl": "1.0.2", 433 | "escape-html": "1.0.3", 434 | "etag": "1.8.1", 435 | "finalhandler": "1.1.1", 436 | "fresh": "0.5.2", 437 | "merge-descriptors": "1.0.1", 438 | "methods": "1.1.2", 439 | "on-finished": "2.3.0", 440 | "parseurl": "1.3.2", 441 | "path-to-regexp": "0.1.7", 442 | "proxy-addr": "2.0.3", 443 | "qs": "6.5.1", 444 | "range-parser": "1.2.0", 445 | "safe-buffer": "5.1.1", 446 | "send": "0.16.2", 447 | "serve-static": "1.13.2", 448 | "setprototypeof": "1.1.0", 449 | "statuses": "1.4.0", 450 | "type-is": "1.6.16", 451 | "utils-merge": "1.0.1", 452 | "vary": "1.1.2" 453 | } 454 | }, 455 | "extend": { 456 | "version": "3.0.1", 457 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 458 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" 459 | }, 460 | "extsprintf": { 461 | "version": "1.3.0", 462 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 463 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 464 | }, 465 | "fast-deep-equal": { 466 | "version": "1.1.0", 467 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 468 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 469 | }, 470 | "fast-json-stable-stringify": { 471 | "version": "2.0.0", 472 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 473 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 474 | }, 475 | "finalhandler": { 476 | "version": "1.1.1", 477 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 478 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 479 | "requires": { 480 | "debug": "2.6.9", 481 | "encodeurl": "1.0.2", 482 | "escape-html": "1.0.3", 483 | "on-finished": "2.3.0", 484 | "parseurl": "1.3.2", 485 | "statuses": "1.4.0", 486 | "unpipe": "1.0.0" 487 | } 488 | }, 489 | "forever-agent": { 490 | "version": "0.6.1", 491 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 492 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 493 | }, 494 | "form-data": { 495 | "version": "2.3.2", 496 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 497 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 498 | "requires": { 499 | "asynckit": "0.4.0", 500 | "combined-stream": "1.0.6", 501 | "mime-types": "2.1.18" 502 | } 503 | }, 504 | "forwarded": { 505 | "version": "0.1.2", 506 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 507 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 508 | }, 509 | "fresh": { 510 | "version": "0.5.2", 511 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 512 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 513 | }, 514 | "getpass": { 515 | "version": "0.1.7", 516 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 517 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 518 | "requires": { 519 | "assert-plus": "1.0.0" 520 | } 521 | }, 522 | "graceful-fs": { 523 | "version": "4.1.11", 524 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 525 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 526 | }, 527 | "har-schema": { 528 | "version": "2.0.0", 529 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 530 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 531 | }, 532 | "har-validator": { 533 | "version": "5.0.3", 534 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", 535 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", 536 | "requires": { 537 | "ajv": "5.5.2", 538 | "har-schema": "2.0.0" 539 | } 540 | }, 541 | "has-binary": { 542 | "version": "0.1.7", 543 | "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", 544 | "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", 545 | "requires": { 546 | "isarray": "0.0.1" 547 | } 548 | }, 549 | "has-cors": { 550 | "version": "1.1.0", 551 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", 552 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" 553 | }, 554 | "hawk": { 555 | "version": "6.0.2", 556 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", 557 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", 558 | "requires": { 559 | "boom": "4.3.1", 560 | "cryptiles": "3.1.2", 561 | "hoek": "4.2.1", 562 | "sntp": "2.1.0" 563 | } 564 | }, 565 | "hoek": { 566 | "version": "4.2.1", 567 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", 568 | "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" 569 | }, 570 | "http-errors": { 571 | "version": "1.6.2", 572 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 573 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 574 | "requires": { 575 | "depd": "1.1.1", 576 | "inherits": "2.0.3", 577 | "setprototypeof": "1.0.3", 578 | "statuses": "1.4.0" 579 | }, 580 | "dependencies": { 581 | "depd": { 582 | "version": "1.1.1", 583 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 584 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 585 | }, 586 | "setprototypeof": { 587 | "version": "1.0.3", 588 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 589 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 590 | } 591 | } 592 | }, 593 | "http-signature": { 594 | "version": "1.2.0", 595 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 596 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 597 | "requires": { 598 | "assert-plus": "1.0.0", 599 | "jsprim": "1.4.1", 600 | "sshpk": "1.14.1" 601 | } 602 | }, 603 | "iconv-lite": { 604 | "version": "0.4.19", 605 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 606 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 607 | }, 608 | "indexof": { 609 | "version": "0.0.1", 610 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", 611 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" 612 | }, 613 | "inherits": { 614 | "version": "2.0.3", 615 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 616 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 617 | }, 618 | "ipaddr.js": { 619 | "version": "1.6.0", 620 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", 621 | "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" 622 | }, 623 | "is-typedarray": { 624 | "version": "1.0.0", 625 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 626 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 627 | }, 628 | "isarray": { 629 | "version": "0.0.1", 630 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 631 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 632 | }, 633 | "isstream": { 634 | "version": "0.1.2", 635 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 636 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 637 | }, 638 | "jsbn": { 639 | "version": "0.1.1", 640 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 641 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 642 | "optional": true 643 | }, 644 | "json-schema": { 645 | "version": "0.2.3", 646 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 647 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 648 | }, 649 | "json-schema-traverse": { 650 | "version": "0.3.1", 651 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 652 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 653 | }, 654 | "json-stringify-safe": { 655 | "version": "5.0.1", 656 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 657 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 658 | }, 659 | "json3": { 660 | "version": "3.3.2", 661 | "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", 662 | "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" 663 | }, 664 | "jsprim": { 665 | "version": "1.4.1", 666 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 667 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 668 | "requires": { 669 | "assert-plus": "1.0.0", 670 | "extsprintf": "1.3.0", 671 | "json-schema": "0.2.3", 672 | "verror": "1.10.0" 673 | } 674 | }, 675 | "lock": { 676 | "version": "0.1.4", 677 | "resolved": "https://registry.npmjs.org/lock/-/lock-0.1.4.tgz", 678 | "integrity": "sha1-/sfervF+fDoKVeHaBCgD4l2RdF0=" 679 | }, 680 | "lodash": { 681 | "version": "4.17.5", 682 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", 683 | "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" 684 | }, 685 | "media-typer": { 686 | "version": "0.3.0", 687 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 688 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 689 | }, 690 | "merge-descriptors": { 691 | "version": "1.0.1", 692 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 693 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 694 | }, 695 | "methods": { 696 | "version": "1.1.2", 697 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 698 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 699 | }, 700 | "mime": { 701 | "version": "1.4.1", 702 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 703 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 704 | }, 705 | "mime-db": { 706 | "version": "1.33.0", 707 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 708 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 709 | }, 710 | "mime-types": { 711 | "version": "2.1.18", 712 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 713 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 714 | "requires": { 715 | "mime-db": "1.33.0" 716 | } 717 | }, 718 | "mkpath": { 719 | "version": "0.1.0", 720 | "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", 721 | "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" 722 | }, 723 | "ms": { 724 | "version": "2.0.0", 725 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 726 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 727 | }, 728 | "negotiator": { 729 | "version": "0.6.1", 730 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 731 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 732 | }, 733 | "ngrok": { 734 | "version": "2.2.26", 735 | "resolved": "https://registry.npmjs.org/ngrok/-/ngrok-2.2.26.tgz", 736 | "integrity": "sha512-DAWmOerUpBvtjLnX+Da9iE5JFCCWXBqYVFwjQtllnveIHL+u/TRjtsYqg4zttkoXXceG+gGon92atDGQd2SgiA==", 737 | "requires": { 738 | "@types/node": "8.9.5", 739 | "async": "2.6.0", 740 | "decompress-zip": "0.3.0", 741 | "lock": "0.1.4", 742 | "request": "2.85.0", 743 | "uuid": "3.2.1" 744 | } 745 | }, 746 | "nopt": { 747 | "version": "3.0.6", 748 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 749 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 750 | "requires": { 751 | "abbrev": "1.1.1" 752 | } 753 | }, 754 | "oauth-sign": { 755 | "version": "0.8.2", 756 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 757 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" 758 | }, 759 | "object-assign": { 760 | "version": "4.1.0", 761 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", 762 | "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" 763 | }, 764 | "object-component": { 765 | "version": "0.0.3", 766 | "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", 767 | "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" 768 | }, 769 | "on-finished": { 770 | "version": "2.3.0", 771 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 772 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 773 | "requires": { 774 | "ee-first": "1.1.1" 775 | } 776 | }, 777 | "options": { 778 | "version": "0.0.6", 779 | "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", 780 | "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" 781 | }, 782 | "parsejson": { 783 | "version": "0.0.3", 784 | "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", 785 | "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", 786 | "requires": { 787 | "better-assert": "1.0.2" 788 | } 789 | }, 790 | "parseqs": { 791 | "version": "0.0.5", 792 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", 793 | "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", 794 | "requires": { 795 | "better-assert": "1.0.2" 796 | } 797 | }, 798 | "parseuri": { 799 | "version": "0.0.5", 800 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", 801 | "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", 802 | "requires": { 803 | "better-assert": "1.0.2" 804 | } 805 | }, 806 | "parseurl": { 807 | "version": "1.3.2", 808 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 809 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 810 | }, 811 | "path-to-regexp": { 812 | "version": "0.1.7", 813 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 814 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 815 | }, 816 | "performance-now": { 817 | "version": "2.1.0", 818 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 819 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 820 | }, 821 | "proxy-addr": { 822 | "version": "2.0.3", 823 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", 824 | "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", 825 | "requires": { 826 | "forwarded": "0.1.2", 827 | "ipaddr.js": "1.6.0" 828 | } 829 | }, 830 | "punycode": { 831 | "version": "1.4.1", 832 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 833 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 834 | }, 835 | "q": { 836 | "version": "1.5.1", 837 | "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", 838 | "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" 839 | }, 840 | "qs": { 841 | "version": "6.5.1", 842 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 843 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 844 | }, 845 | "range-parser": { 846 | "version": "1.2.0", 847 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 848 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 849 | }, 850 | "raw-body": { 851 | "version": "2.3.2", 852 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 853 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 854 | "requires": { 855 | "bytes": "3.0.0", 856 | "http-errors": "1.6.2", 857 | "iconv-lite": "0.4.19", 858 | "unpipe": "1.0.0" 859 | } 860 | }, 861 | "readable-stream": { 862 | "version": "1.1.14", 863 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 864 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 865 | "requires": { 866 | "core-util-is": "1.0.2", 867 | "inherits": "2.0.3", 868 | "isarray": "0.0.1", 869 | "string_decoder": "0.10.31" 870 | }, 871 | "dependencies": { 872 | "isarray": { 873 | "version": "0.0.1", 874 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 875 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 876 | } 877 | } 878 | }, 879 | "request": { 880 | "version": "2.85.0", 881 | "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", 882 | "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", 883 | "requires": { 884 | "aws-sign2": "0.7.0", 885 | "aws4": "1.6.0", 886 | "caseless": "0.12.0", 887 | "combined-stream": "1.0.6", 888 | "extend": "3.0.1", 889 | "forever-agent": "0.6.1", 890 | "form-data": "2.3.2", 891 | "har-validator": "5.0.3", 892 | "hawk": "6.0.2", 893 | "http-signature": "1.2.0", 894 | "is-typedarray": "1.0.0", 895 | "isstream": "0.1.2", 896 | "json-stringify-safe": "5.0.1", 897 | "mime-types": "2.1.18", 898 | "oauth-sign": "0.8.2", 899 | "performance-now": "2.1.0", 900 | "qs": "6.5.1", 901 | "safe-buffer": "5.1.1", 902 | "stringstream": "0.0.5", 903 | "tough-cookie": "2.3.4", 904 | "tunnel-agent": "0.6.0", 905 | "uuid": "3.2.1" 906 | } 907 | }, 908 | "safe-buffer": { 909 | "version": "5.1.1", 910 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 911 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 912 | }, 913 | "send": { 914 | "version": "0.16.2", 915 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 916 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 917 | "requires": { 918 | "debug": "2.6.9", 919 | "depd": "1.1.2", 920 | "destroy": "1.0.4", 921 | "encodeurl": "1.0.2", 922 | "escape-html": "1.0.3", 923 | "etag": "1.8.1", 924 | "fresh": "0.5.2", 925 | "http-errors": "1.6.2", 926 | "mime": "1.4.1", 927 | "ms": "2.0.0", 928 | "on-finished": "2.3.0", 929 | "range-parser": "1.2.0", 930 | "statuses": "1.4.0" 931 | } 932 | }, 933 | "serve-static": { 934 | "version": "1.13.2", 935 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 936 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 937 | "requires": { 938 | "encodeurl": "1.0.2", 939 | "escape-html": "1.0.3", 940 | "parseurl": "1.3.2", 941 | "send": "0.16.2" 942 | } 943 | }, 944 | "setprototypeof": { 945 | "version": "1.1.0", 946 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 947 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 948 | }, 949 | "sntp": { 950 | "version": "2.1.0", 951 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", 952 | "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", 953 | "requires": { 954 | "hoek": "4.2.1" 955 | } 956 | }, 957 | "socket.io": { 958 | "version": "1.7.4", 959 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.4.tgz", 960 | "integrity": "sha1-L37O3DORvy1cc+KR/iM+bjTU3QA=", 961 | "requires": { 962 | "debug": "2.3.3", 963 | "engine.io": "1.8.5", 964 | "has-binary": "0.1.7", 965 | "object-assign": "4.1.0", 966 | "socket.io-adapter": "0.5.0", 967 | "socket.io-client": "1.7.4", 968 | "socket.io-parser": "2.3.1" 969 | }, 970 | "dependencies": { 971 | "debug": { 972 | "version": "2.3.3", 973 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", 974 | "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", 975 | "requires": { 976 | "ms": "0.7.2" 977 | } 978 | }, 979 | "ms": { 980 | "version": "0.7.2", 981 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", 982 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" 983 | } 984 | } 985 | }, 986 | "socket.io-adapter": { 987 | "version": "0.5.0", 988 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", 989 | "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", 990 | "requires": { 991 | "debug": "2.3.3", 992 | "socket.io-parser": "2.3.1" 993 | }, 994 | "dependencies": { 995 | "debug": { 996 | "version": "2.3.3", 997 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", 998 | "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", 999 | "requires": { 1000 | "ms": "0.7.2" 1001 | } 1002 | }, 1003 | "ms": { 1004 | "version": "0.7.2", 1005 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", 1006 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" 1007 | } 1008 | } 1009 | }, 1010 | "socket.io-client": { 1011 | "version": "1.7.4", 1012 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz", 1013 | "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=", 1014 | "requires": { 1015 | "backo2": "1.0.2", 1016 | "component-bind": "1.0.0", 1017 | "component-emitter": "1.2.1", 1018 | "debug": "2.3.3", 1019 | "engine.io-client": "1.8.5", 1020 | "has-binary": "0.1.7", 1021 | "indexof": "0.0.1", 1022 | "object-component": "0.0.3", 1023 | "parseuri": "0.0.5", 1024 | "socket.io-parser": "2.3.1", 1025 | "to-array": "0.1.4" 1026 | }, 1027 | "dependencies": { 1028 | "component-emitter": { 1029 | "version": "1.2.1", 1030 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 1031 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 1032 | }, 1033 | "debug": { 1034 | "version": "2.3.3", 1035 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", 1036 | "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", 1037 | "requires": { 1038 | "ms": "0.7.2" 1039 | } 1040 | }, 1041 | "ms": { 1042 | "version": "0.7.2", 1043 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", 1044 | "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" 1045 | } 1046 | } 1047 | }, 1048 | "socket.io-parser": { 1049 | "version": "2.3.1", 1050 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", 1051 | "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", 1052 | "requires": { 1053 | "component-emitter": "1.1.2", 1054 | "debug": "2.2.0", 1055 | "isarray": "0.0.1", 1056 | "json3": "3.3.2" 1057 | }, 1058 | "dependencies": { 1059 | "debug": { 1060 | "version": "2.2.0", 1061 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", 1062 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", 1063 | "requires": { 1064 | "ms": "0.7.1" 1065 | } 1066 | }, 1067 | "ms": { 1068 | "version": "0.7.1", 1069 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", 1070 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" 1071 | } 1072 | } 1073 | }, 1074 | "sshpk": { 1075 | "version": "1.14.1", 1076 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", 1077 | "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", 1078 | "requires": { 1079 | "asn1": "0.2.3", 1080 | "assert-plus": "1.0.0", 1081 | "bcrypt-pbkdf": "1.0.1", 1082 | "dashdash": "1.14.1", 1083 | "ecc-jsbn": "0.1.1", 1084 | "getpass": "0.1.7", 1085 | "jsbn": "0.1.1", 1086 | "tweetnacl": "0.14.5" 1087 | } 1088 | }, 1089 | "statuses": { 1090 | "version": "1.4.0", 1091 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 1092 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 1093 | }, 1094 | "string_decoder": { 1095 | "version": "0.10.31", 1096 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1097 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1098 | }, 1099 | "stringstream": { 1100 | "version": "0.0.5", 1101 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 1102 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" 1103 | }, 1104 | "to-array": { 1105 | "version": "0.1.4", 1106 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", 1107 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" 1108 | }, 1109 | "touch": { 1110 | "version": "0.0.3", 1111 | "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", 1112 | "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", 1113 | "requires": { 1114 | "nopt": "1.0.10" 1115 | }, 1116 | "dependencies": { 1117 | "nopt": { 1118 | "version": "1.0.10", 1119 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 1120 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", 1121 | "requires": { 1122 | "abbrev": "1.1.1" 1123 | } 1124 | } 1125 | } 1126 | }, 1127 | "tough-cookie": { 1128 | "version": "2.3.4", 1129 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", 1130 | "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", 1131 | "requires": { 1132 | "punycode": "1.4.1" 1133 | } 1134 | }, 1135 | "traverse": { 1136 | "version": "0.3.9", 1137 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", 1138 | "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" 1139 | }, 1140 | "tunnel-agent": { 1141 | "version": "0.6.0", 1142 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1143 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1144 | "requires": { 1145 | "safe-buffer": "5.1.1" 1146 | } 1147 | }, 1148 | "tweetnacl": { 1149 | "version": "0.14.5", 1150 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1151 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 1152 | "optional": true 1153 | }, 1154 | "type-is": { 1155 | "version": "1.6.16", 1156 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 1157 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 1158 | "requires": { 1159 | "media-typer": "0.3.0", 1160 | "mime-types": "2.1.18" 1161 | } 1162 | }, 1163 | "ultron": { 1164 | "version": "1.0.2", 1165 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", 1166 | "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" 1167 | }, 1168 | "unpipe": { 1169 | "version": "1.0.0", 1170 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1171 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1172 | }, 1173 | "utils-merge": { 1174 | "version": "1.0.1", 1175 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1176 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1177 | }, 1178 | "uuid": { 1179 | "version": "3.2.1", 1180 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", 1181 | "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" 1182 | }, 1183 | "vary": { 1184 | "version": "1.1.2", 1185 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1186 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1187 | }, 1188 | "verror": { 1189 | "version": "1.10.0", 1190 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1191 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1192 | "requires": { 1193 | "assert-plus": "1.0.0", 1194 | "core-util-is": "1.0.2", 1195 | "extsprintf": "1.3.0" 1196 | } 1197 | }, 1198 | "ws": { 1199 | "version": "1.1.5", 1200 | "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", 1201 | "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", 1202 | "requires": { 1203 | "options": "0.0.6", 1204 | "ultron": "1.0.2" 1205 | } 1206 | }, 1207 | "wtf-8": { 1208 | "version": "1.0.0", 1209 | "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", 1210 | "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=" 1211 | }, 1212 | "xmlhttprequest-ssl": { 1213 | "version": "1.5.3", 1214 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", 1215 | "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=" 1216 | }, 1217 | "yeast": { 1218 | "version": "0.1.2", 1219 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", 1220 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" 1221 | } 1222 | } 1223 | } 1224 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webrtc-simple-signaling-server", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "SEE LICENSE IN README", 11 | "dependencies": { 12 | "express": "^4.16.3", 13 | "ngrok": "~2.2", 14 | "socket.io": "~1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/server.bat: -------------------------------------------------------------------------------- 1 | 2 | call npm install 3 | 4 | node index.js 5 | 6 | pause 7 | --------------------------------------------------------------------------------