func (s *recordingServiceServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
	writeError(ctx, resp, err, s.hooks)
}
writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
package livekit
import context "context"
import fmt "fmt"
import http "net/http"
import ioutil "io/ioutil"
import json "encoding/json"
import strconv "strconv"
import strings "strings"
import protojson "google.golang.org/protobuf/encoding/protojson"
import proto "google.golang.org/protobuf/proto"
import twirp "github.com/twitchtv/twirp"
import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
import google_protobuf "google.golang.org/protobuf/types/known/emptypb"
import bytes "bytes"
import errors "errors"
import io "io"
import path "path"
import url "net/url"
const _ = twirp.TwirpPackageMinVersion_8_1_0
type RecordingService interface {
	StartRecording(context.Context, *StartRecordingRequest) (*StartRecordingResponse, error)
	AddOutput(context.Context, *AddOutputRequest) (*google_protobuf.Empty, error)
	RemoveOutput(context.Context, *RemoveOutputRequest) (*google_protobuf.Empty, error)
	EndRecording(context.Context, *EndRecordingRequest) (*google_protobuf.Empty, error)
}
type recordingServiceProtobufClient struct {
	client      HTTPClient
	urls        [4]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}
func NewRecordingServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) RecordingService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}
	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}
	literalURLs := false
	_ = clientOpts.ReadOpt("literalURLs", &literalURLs)
	var pathPrefix string
	if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
		pathPrefix = "/twirp"  
	}
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(pathPrefix, "livekit", "RecordingService")
	urls := [4]string{
		serviceURL + "StartRecording",
		serviceURL + "AddOutput",
		serviceURL + "RemoveOutput",
		serviceURL + "EndRecording",
	}
	return &recordingServiceProtobufClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}
func (c *recordingServiceProtobufClient) StartRecording(ctx context.Context, in *StartRecordingRequest) (*StartRecordingResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "StartRecording")
	caller := c.callStartRecording
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *StartRecordingRequest) (*StartRecordingResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*StartRecordingRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*StartRecordingRequest) when calling interceptor")
					}
					return c.callStartRecording(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*StartRecordingResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*StartRecordingResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceProtobufClient) callStartRecording(ctx context.Context, in *StartRecordingRequest) (*StartRecordingResponse, error) {
	out := new(StartRecordingResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceProtobufClient) AddOutput(ctx context.Context, in *AddOutputRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "AddOutput")
	caller := c.callAddOutput
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddOutputRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddOutputRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddOutputRequest) when calling interceptor")
					}
					return c.callAddOutput(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceProtobufClient) callAddOutput(ctx context.Context, in *AddOutputRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceProtobufClient) RemoveOutput(ctx context.Context, in *RemoveOutputRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "RemoveOutput")
	caller := c.callRemoveOutput
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *RemoveOutputRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*RemoveOutputRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*RemoveOutputRequest) when calling interceptor")
					}
					return c.callRemoveOutput(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceProtobufClient) callRemoveOutput(ctx context.Context, in *RemoveOutputRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceProtobufClient) EndRecording(ctx context.Context, in *EndRecordingRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "EndRecording")
	caller := c.callEndRecording
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *EndRecordingRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*EndRecordingRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*EndRecordingRequest) when calling interceptor")
					}
					return c.callEndRecording(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceProtobufClient) callEndRecording(ctx context.Context, in *EndRecordingRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
type recordingServiceJSONClient struct {
	client      HTTPClient
	urls        [4]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}
func NewRecordingServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) RecordingService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}
	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}
	literalURLs := false
	_ = clientOpts.ReadOpt("literalURLs", &literalURLs)
	var pathPrefix string
	if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
		pathPrefix = "/twirp"  
	}
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(pathPrefix, "livekit", "RecordingService")
	urls := [4]string{
		serviceURL + "StartRecording",
		serviceURL + "AddOutput",
		serviceURL + "RemoveOutput",
		serviceURL + "EndRecording",
	}
	return &recordingServiceJSONClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}
func (c *recordingServiceJSONClient) StartRecording(ctx context.Context, in *StartRecordingRequest) (*StartRecordingResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "StartRecording")
	caller := c.callStartRecording
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *StartRecordingRequest) (*StartRecordingResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*StartRecordingRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*StartRecordingRequest) when calling interceptor")
					}
					return c.callStartRecording(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*StartRecordingResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*StartRecordingResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceJSONClient) callStartRecording(ctx context.Context, in *StartRecordingRequest) (*StartRecordingResponse, error) {
	out := new(StartRecordingResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceJSONClient) AddOutput(ctx context.Context, in *AddOutputRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "AddOutput")
	caller := c.callAddOutput
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddOutputRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddOutputRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddOutputRequest) when calling interceptor")
					}
					return c.callAddOutput(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceJSONClient) callAddOutput(ctx context.Context, in *AddOutputRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceJSONClient) RemoveOutput(ctx context.Context, in *RemoveOutputRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "RemoveOutput")
	caller := c.callRemoveOutput
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *RemoveOutputRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*RemoveOutputRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*RemoveOutputRequest) when calling interceptor")
					}
					return c.callRemoveOutput(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceJSONClient) callRemoveOutput(ctx context.Context, in *RemoveOutputRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
func (c *recordingServiceJSONClient) EndRecording(ctx context.Context, in *EndRecordingRequest) (*google_protobuf.Empty, error) {
	ctx = ctxsetters.WithPackageName(ctx, "livekit")
	ctx = ctxsetters.WithServiceName(ctx, "RecordingService")
	ctx = ctxsetters.WithMethodName(ctx, "EndRecording")
	caller := c.callEndRecording
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *EndRecordingRequest) (*google_protobuf.Empty, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*EndRecordingRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*EndRecordingRequest) when calling interceptor")
					}
					return c.callEndRecording(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*google_protobuf.Empty)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}
func (c *recordingServiceJSONClient) callEndRecording(ctx context.Context, in *EndRecordingRequest) (*google_protobuf.Empty, error) {
	out := new(google_protobuf.Empty)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}
	callClientResponseReceived(ctx, c.opts.Hooks)
	return out, nil
}
type recordingServiceServer struct {
	RecordingService
	interceptor      twirp.Interceptor
	hooks            *twirp.ServerHooks
	pathPrefix       string  
	jsonSkipDefaults bool    
	jsonCamelCase    bool    
}
func NewRecordingServiceServer(svc RecordingService, opts ...interface{}) TwirpServer {
	serverOpts := newServerOpts(opts)
	jsonSkipDefaults := false
	_ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults)
	jsonCamelCase := false
	_ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase)
	var pathPrefix string
	if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
		pathPrefix = "/twirp"  
	}
	return &recordingServiceServer{
		RecordingService: svc,
		hooks:            serverOpts.Hooks,
		interceptor:      twirp.ChainInterceptors(serverOpts.Interceptors...),
		pathPrefix:       pathPrefix,
		jsonSkipDefaults: jsonSkipDefaults,
		jsonCamelCase:    jsonCamelCase,
	}
}