StreamViewer.xaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /* StreamViewer.xaml.cs/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro). */
  2. /* This copyright was auto-generated on Wed Oct 20 21:41:18 UTC 2021 */
  3. using Microsoft.Win32;
  4. using System;
  5. using System.ComponentModel;
  6. using System.Globalization;
  7. using System.IO;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Windows;
  13. using System.Windows.Controls;
  14. namespace GoProWebcamViewer
  15. {
  16. enum Status
  17. {
  18. SUCCESS,
  19. FAILURE
  20. }
  21. /// <summary>
  22. /// Interaction logic for StreamViewer.xaml
  23. /// </summary>
  24. public partial class StreamViewer : Window, INotifyPropertyChanged
  25. {
  26. bool bQuit = false;
  27. bool zoomMan = false;
  28. private string playerEnabledText, webcamEnabledText, previewEnabledText;
  29. private bool playerEnabled
  30. {
  31. get { return playerEnabledText == "enabled" ? true : false; }
  32. set
  33. {
  34. playerEnabledText = value == true ? "enabled" : "disabled";
  35. UpdateStatusBar();
  36. }
  37. }
  38. private bool webcamEnabled
  39. {
  40. get { return webcamEnabledText == "enabled" ? true : false; }
  41. set
  42. {
  43. webcamEnabledText = value == true ? "enabled" : "disabled";
  44. UpdateStatusBar();
  45. }
  46. }
  47. private bool previewEnabled
  48. {
  49. get { return previewEnabledText == "enabled" ? true : false; }
  50. set
  51. {
  52. previewEnabledText = value == true ? "enabled" : "disabled";
  53. UpdateStatusBar();
  54. }
  55. }
  56. private string ipaddr = "unknown";
  57. public event PropertyChangedEventHandler PropertyChanged;
  58. public string IPAddr
  59. {
  60. get { return ipaddr; }
  61. set
  62. {
  63. ipaddr = value;
  64. OnPropertyChanged("IPAddr");
  65. }
  66. }
  67. public StreamViewer()
  68. {
  69. InitializeComponent();
  70. this.Top = Properties.Settings.Default.FTop;
  71. this.Left = Properties.Settings.Default.FLeft;
  72. this.Height = Properties.Settings.Default.FHeight;
  73. this.Width = Properties.Settings.Default.FWidth;
  74. if (this.Height == 0)
  75. {
  76. this.Height = 600;
  77. this.Width = 800;
  78. }
  79. ipaddr = Properties.Settings.Default.IPAddress;
  80. this.txtIPAddr.Text = ipaddr;
  81. DataContext = this;
  82. var vlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine("./", "libvlc", IntPtr.Size == 4 ? "win-x86" : "win-x64"));
  83. var options = new string[]
  84. {
  85. // VLC options can be given here. Please refer to the VLC command line documentation.
  86. };
  87. mPlayer.SourceProvider.CreatePlayer(vlcLibDirectory, options);
  88. new Timer(IPAddrCheck, this, 50, 10000);
  89. playerEnabled = false;
  90. webcamEnabled = false;
  91. previewEnabled = false;
  92. }
  93. private void Log(string text)
  94. {
  95. Dispatcher.Invoke((Action)delegate ()
  96. { /* update UI */
  97. this.txtGeneral.Text += text;
  98. });
  99. }
  100. private void UpdateStatusBar()
  101. {
  102. Dispatcher.Invoke((Action)delegate ()
  103. { /* update UI */
  104. this.txtStatusBar.Text = $"Player: {playerEnabledText,-20}Webcam: {webcamEnabledText,-20}Preview: {previewEnabledText,-20}";
  105. });
  106. }
  107. private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  108. {
  109. bQuit = true;
  110. ThreadPool.QueueUserWorkItem(_ => mPlayer.SourceProvider.MediaPlayer.Stop());
  111. if (WindowState == WindowState.Maximized)
  112. {
  113. // Use the RestoreBounds as the current values will be 0, 0 and the size of the screen
  114. Properties.Settings.Default.FTop = RestoreBounds.Top;
  115. Properties.Settings.Default.FLeft = RestoreBounds.Left;
  116. Properties.Settings.Default.FHeight = RestoreBounds.Height;
  117. Properties.Settings.Default.FWidth = RestoreBounds.Width;
  118. }
  119. else
  120. {
  121. Properties.Settings.Default.FTop = this.Top;
  122. Properties.Settings.Default.FLeft = this.Left;
  123. Properties.Settings.Default.FHeight = this.Height;
  124. Properties.Settings.Default.FWidth = this.Width;
  125. }
  126. Properties.Settings.Default.IPAddress = ipaddr;
  127. Properties.Settings.Default.Save();
  128. }
  129. private Status SendHTTPRequest(string endpoint)
  130. {
  131. Status status = Status.FAILURE;
  132. if (ipaddr == "not found")
  133. return status;
  134. string responseString;
  135. string requestString = "http://" + ipaddr + ":8080/gopro/" + endpoint;
  136. HttpWebResponse resp;
  137. HttpWebRequest req = HttpWebRequest.CreateHttp(requestString);
  138. req.Method = "GET";
  139. req.KeepAlive = false;
  140. try
  141. {
  142. Log(requestString + " ==> \n");
  143. resp = (HttpWebResponse)req.GetResponse();
  144. responseString = new StreamReader(resp.GetResponseStream()).ReadToEnd();
  145. resp.Close();
  146. status = Status.SUCCESS;
  147. }
  148. catch (WebException ep)
  149. {
  150. responseString = "Failed url " + endpoint + ": " + ep.Message;
  151. HttpWebResponse respy = (HttpWebResponse)ep.Response;
  152. if (respy != null)
  153. {
  154. responseString = new StreamReader(respy.GetResponseStream()).ReadToEnd();
  155. }
  156. }
  157. if (!bQuit)
  158. {
  159. Log(responseString);
  160. }
  161. return status;
  162. }
  163. private Status SetSetting(int id, int value)
  164. {
  165. return SendHTTPRequest("camera/setting?setting=" + id.ToString() + "&option=" + value.ToString());
  166. }
  167. private void btnStatusStream_Click(object sender, RoutedEventArgs e)
  168. {
  169. SendHTTPRequest("webcam/status");
  170. }
  171. private void btnClearText_Click(object sender, RoutedEventArgs e)
  172. {
  173. txtGeneral.Clear();
  174. txtStatusBar.Text = "";
  175. }
  176. private void HideStream()
  177. {
  178. ThreadPool.QueueUserWorkItem(_ => mPlayer.SourceProvider.MediaPlayer.Stop());
  179. playerEnabled = false;
  180. }
  181. private void sldZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
  182. {
  183. if (!zoomMan)
  184. {
  185. SendHTTPRequest("camera/digital_zoom?percent=" + Convert.ToInt32(sldZoom.Value));
  186. }
  187. }
  188. private void Thumb_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
  189. {
  190. zoomMan = true;
  191. }
  192. private void Thumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
  193. {
  194. zoomMan = false;
  195. SendHTTPRequest("camera/digital_zoom?percent=" + Convert.ToInt32(sldZoom.Value));
  196. }
  197. private void btnFOV_Click(object sender, RoutedEventArgs e)
  198. {
  199. int value = Convert.ToInt32(((ComboBoxItem)cmbFOV.SelectedItem).Content.ToString());
  200. SetSetting(43, value);
  201. }
  202. private void txtIPAddr_TextChanged(object sender, TextChangedEventArgs e)
  203. {
  204. ipaddr = txtIPAddr.Text;
  205. }
  206. private void IPAddrCheck(object state)
  207. {
  208. String strHostName = Dns.GetHostName();
  209. bool found = false;
  210. // Find host by name
  211. IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
  212. // Enumerate IP addresses
  213. foreach (IPAddress ipaddress in iphostentry.AddressList)
  214. {
  215. if (ipaddress.AddressFamily == AddressFamily.InterNetwork)
  216. {
  217. byte[] abytes = ipaddress.GetAddressBytes();
  218. if (abytes[0] == 172 && abytes[1] >= 20 && abytes[1] <= 29 && abytes[3] >= 50 && abytes[3] <= 70)
  219. {
  220. ipaddr = ipaddress.ToString();
  221. StringBuilder sb = new StringBuilder(ipaddress.ToString());
  222. sb[ipaddress.ToString().Length - 1] = '1';
  223. IPAddr = sb.ToString();
  224. found = true;
  225. break;
  226. }
  227. }
  228. }
  229. if (!found)
  230. IPAddr = "not found";
  231. }
  232. protected void OnPropertyChanged(string name = null)
  233. {
  234. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
  235. }
  236. private void btnPreview_Click(object sender, RoutedEventArgs e)
  237. {
  238. if (SendHTTPRequest("webcam/preview") == Status.SUCCESS)
  239. {
  240. btnFOV.IsEnabled = true;
  241. sldZoom.IsEnabled = true;
  242. previewEnabled = true;
  243. webcamEnabled = false;
  244. }
  245. }
  246. private void btnStart_Click(object sender, RoutedEventArgs e)
  247. {
  248. if (SendHTTPRequest("webcam/start") == Status.SUCCESS)
  249. {
  250. btnFOV.IsEnabled = false;
  251. sldZoom.IsEnabled = false;
  252. webcamEnabled = true;
  253. previewEnabled = false;
  254. }
  255. }
  256. private void btnStop_Click(object sender, RoutedEventArgs e)
  257. {
  258. if (SendHTTPRequest("webcam/stop") == Status.SUCCESS)
  259. {
  260. HideStream();
  261. btnFOV.IsEnabled = false;
  262. sldZoom.IsEnabled = false;
  263. webcamEnabled = false;
  264. }
  265. }
  266. private void btnExit_Click(object sender, RoutedEventArgs e)
  267. {
  268. if (SendHTTPRequest("webcam/exit") == Status.SUCCESS)
  269. {
  270. HideStream();
  271. btnFOV.IsEnabled = false;
  272. sldZoom.IsEnabled = false;
  273. webcamEnabled = false;
  274. previewEnabled = false;
  275. }
  276. }
  277. private void btnStartPlayer_Click(object sender, RoutedEventArgs e)
  278. {
  279. Log("Starting video player...\n");
  280. ThreadPool.QueueUserWorkItem(_ =>
  281. {
  282. mPlayer.SourceProvider.MediaPlayer.Play(new Uri("udp://@0.0.0.0:8554", UriKind.Absolute), new string[] { "--network-caching=10", "--no-audio" });
  283. });
  284. playerEnabled = true;
  285. }
  286. private void btnStopPlayer_Click(object sender, RoutedEventArgs e)
  287. {
  288. Log("Stopping video player...\n");
  289. HideStream();
  290. }
  291. private void btnMute_Click(object sender, RoutedEventArgs e)
  292. {
  293. Log("Toggling mute...\n");
  294. ThreadPool.QueueUserWorkItem(_ => mPlayer.SourceProvider.MediaPlayer.Audio.ToggleMute());
  295. }
  296. }
  297. }