diff --git a/src/views/Publication/Services/Azure.js b/src/views/Publication/Services/Azure.js
new file mode 100644
index 0000000..54ca753
--- /dev/null
+++ b/src/views/Publication/Services/Azure.js
@@ -0,0 +1,106 @@
+import React from 'react';
+
+import { Trans } from '@lingui/macro';
+import Grid from '@mui/material/Grid';
+import Link from '@mui/material/Link';
+import MenuItem from '@mui/material/MenuItem';
+import Select from '../../../misc/Select';
+import TextField from '@mui/material/TextField';
+
+import Logo from './logos/azure.svg';
+
+const id = 'azure';
+const name = 'Azure Media Services';
+const version = '1.0';
+const stream_key_link = '';
+const description = (
+
+ Transmit to a Azure Media Services. More details can be found{' '}
+
+ here
+
+ .
+
+);
+const image_copyright = Please contact the operator of the service and check what happens.;
+const author = {
+ creator: {
+ name: 'datarhei',
+ link: 'https://github.com/datarhei',
+ },
+ maintainer: {
+ name: 'datarhei',
+ link: 'https://github.com/datarhei',
+ },
+};
+const category = 'platform';
+const requires = {
+ protocols: ['rtmp', 'rtmps'],
+ formats: ['flv'],
+ codecs: {
+ audio: ['aac', 'mp3'],
+ video: ['h264'],
+ },
+};
+
+function ServiceIcon(props) {
+ return
;
+}
+
+function init(settings) {
+ const initSettings = {
+ protocol: 'rtmp://',
+ address: '',
+ ...settings,
+ };
+
+ return initSettings;
+}
+
+function Service(props) {
+ const settings = init(props.settings);
+
+ const handleChange = (what) => (event) => {
+ const value = event.target.value;
+
+ settings[what] = value;
+
+ const output = createOutput(settings);
+
+ props.onChange([output], settings);
+ };
+
+ const createOutput = (settings) => {
+ const output = {
+ address: settings.protocol + settings.address,
+ options: ['-f', 'flv'],
+ };
+
+ return output;
+ };
+
+ return (
+
+
+
+
+
+ Address} value={settings.address} onChange={handleChange('address')} placeholder="myAccount.channel.mediaservices.windows.net:1935/live/123456789..."
+/>
+
+
+ );
+}
+
+Service.defaultProps = {
+ settings: {},
+ skills: {},
+ metadata: {},
+ streams: [],
+ onChange: function (output, settings) {},
+};
+
+export { id, name, version, stream_key_link, description, image_copyright, author, category, requires, ServiceIcon as icon, Service as component };
diff --git a/src/views/Publication/Services/Linkedin.js b/src/views/Publication/Services/Linkedin.js
new file mode 100644
index 0000000..4defbfe
--- /dev/null
+++ b/src/views/Publication/Services/Linkedin.js
@@ -0,0 +1,105 @@
+import React from 'react';
+
+import { Trans } from '@lingui/macro';
+import Grid from '@mui/material/Grid';
+import Link from '@mui/material/Link';
+import LinkedInIcon from '@mui/icons-material/LinkedIn';
+import MenuItem from '@mui/material/MenuItem';
+import Select from '../../../misc/Select';
+import TextField from '@mui/material/TextField';
+
+const id = 'linkedin';
+const name = 'linkedIn';
+const version = '1.0';
+const stream_key_link = '';
+const description = (
+
+ Transmit to linkedIn. More details can be found{' '}
+
+ here
+
+ .
+
+);
+const image_copyright = Please contact the operator of the service and check what happens.;
+const author = {
+ creator: {
+ name: 'datarhei',
+ link: 'https://github.com/datarhei',
+ },
+ maintainer: {
+ name: 'datarhei',
+ link: 'https://github.com/datarhei',
+ },
+};
+const category = 'platform';
+const requires = {
+ protocols: ['rtmp', 'rtmps'],
+ formats: ['flv'],
+ codecs: {
+ audio: ['aac', 'mp3'],
+ video: ['h264'],
+ },
+};
+
+function ServiceIcon(props) {
+ return ;
+}
+
+function init(settings) {
+ const initSettings = {
+ protocol: 'rtmp://',
+ address: '',
+ ...settings,
+ };
+
+ return initSettings;
+}
+
+function Service(props) {
+ const settings = init(props.settings);
+
+ const handleChange = (what) => (event) => {
+ const value = event.target.value;
+
+ settings[what] = value;
+
+ const output = createOutput(settings);
+
+ props.onChange([output], settings);
+ };
+
+ const createOutput = (settings) => {
+ const output = {
+ address: settings.protocol + settings.address,
+ options: ['-f', 'flv'],
+ };
+
+ return output;
+ };
+
+ return (
+
+
+
+
+
+ Address} value={settings.address} onChange={handleChange('address')} placeholder="{custom_id}.channel.media.azure.net:2935/live/{custom_id}"
+/>
+
+
+ );
+}
+
+Service.defaultProps = {
+ settings: {},
+ skills: {},
+ metadata: {},
+ streams: [],
+ onChange: function (output, settings) {},
+};
+
+export { id, name, version, stream_key_link, description, image_copyright, author, category, requires, ServiceIcon as icon, Service as component };
diff --git a/src/views/Publication/Services/index.js b/src/views/Publication/Services/index.js
index f451e95..123ca17 100644
--- a/src/views/Publication/Services/index.js
+++ b/src/views/Publication/Services/index.js
@@ -1,4 +1,5 @@
import * as Akamai from './Akamai';
+import * as Azure from './Azure';
import * as Brightcove from './Brightcove';
import * as CDN77 from './CDN77';
import * as Core from './Core';
@@ -10,6 +11,7 @@ import * as HLS from './HLS';
import * as Icecast from './Icecast';
import * as Image2 from './Image2';
import * as Instagram from './Instagram';
+import * as Linkedin from './Linkedin';
import * as Livespotting from './Livespotting';
import * as MPEGTS from './MPEGTS';
import * as Owncast from './Owncast';
@@ -65,7 +67,9 @@ registry.Register(Instagram);
registry.Register(Vimeo);
registry.Register(Restream);
registry.Register(Telegram);
+registry.Register(Linkedin);
registry.Register(Livespotting);
+registry.Register(Azure);
registry.Register(Brightcove);
registry.Register(Akamai);
registry.Register(DaCast);
diff --git a/src/views/Publication/Services/logos/azure.svg b/src/views/Publication/Services/logos/azure.svg
new file mode 100644
index 0000000..23b8f31
--- /dev/null
+++ b/src/views/Publication/Services/logos/azure.svg
@@ -0,0 +1,23 @@
+