diff --git a/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m b/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m index 76caddeadf..e54a3d0951 100644 --- a/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m +++ b/submodules/FFMpegBinding/Sources/FFMpegLiveMuxer.m @@ -76,13 +76,15 @@ ret = AVERROR(ENOMEM); goto end; } + + bool hasAudio = false; for (i = 0; i < input_format_context->nb_streams; i++) { AVStream *out_stream; AVStream *in_stream = input_format_context->streams[i]; AVCodecParameters *in_codecpar = in_stream->codecpar; - if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO && in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO) { + if (/*in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO && */in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO) { streams_list[i] = -1; continue; } @@ -110,6 +112,8 @@ ret = AVERROR_UNKNOWN; goto end; } + + hasAudio = true; // Set the codec parameters for the AAC encoder aac_codec_context->sample_rate = in_codecpar->sample_rate; @@ -156,20 +160,22 @@ } } - // Set up the resampling context - swr_ctx = swr_alloc_set_opts(NULL, - aac_codec_context->channel_layout, aac_codec_context->sample_fmt, aac_codec_context->sample_rate, - opus_decoder_context->channel_layout, opus_decoder_context->sample_fmt, opus_decoder_context->sample_rate, - 0, NULL); - if (!swr_ctx) { - fprintf(stderr, "Could not allocate resampler context\n"); - ret = AVERROR(ENOMEM); - goto end; - } - - if ((ret = swr_init(swr_ctx)) < 0) { - fprintf(stderr, "Failed to initialize the resampling context\n"); - goto end; + if (hasAudio) { + // Set up the resampling context + swr_ctx = swr_alloc_set_opts(NULL, + aac_codec_context->channel_layout, aac_codec_context->sample_fmt, aac_codec_context->sample_rate, + opus_decoder_context->channel_layout, opus_decoder_context->sample_fmt, opus_decoder_context->sample_rate, + 0, NULL); + if (!swr_ctx) { + fprintf(stderr, "Could not allocate resampler context\n"); + ret = AVERROR(ENOMEM); + goto end; + } + + if ((ret = swr_init(swr_ctx)) < 0) { + fprintf(stderr, "Failed to initialize the resampling context\n"); + goto end; + } } if (!(output_format_context->oformat->flags & AVFMT_NOFILE)) { diff --git a/submodules/TelegramCallsUI/Sources/Components/MediaStreamComponent.swift b/submodules/TelegramCallsUI/Sources/Components/MediaStreamComponent.swift index 35877a0bd4..0bdfd93fb1 100644 --- a/submodules/TelegramCallsUI/Sources/Components/MediaStreamComponent.swift +++ b/submodules/TelegramCallsUI/Sources/Components/MediaStreamComponent.swift @@ -75,9 +75,9 @@ public final class MediaStreamComponent: CombinedComponent { var videoStalled: Bool = true var videoIsPlayable: Bool { - !videoStalled && hasVideo + return true + //!videoStalled && hasVideo } -// var wantsPiP: Bool = false let deactivatePictureInPictureIfVisible = StoredActionSlot(Void.self) diff --git a/submodules/TelegramCallsUI/Sources/Components/MediaStreamVideoComponent.swift b/submodules/TelegramCallsUI/Sources/Components/MediaStreamVideoComponent.swift index 48a4ae2990..46371e9fb7 100644 --- a/submodules/TelegramCallsUI/Sources/Components/MediaStreamVideoComponent.swift +++ b/submodules/TelegramCallsUI/Sources/Components/MediaStreamVideoComponent.swift @@ -806,116 +806,6 @@ private final class ProxyVideoView: UIView { self.id = Int64.random(in: Int64.min ... Int64.max) - /*if #available(iOS 13.0, *) { - do { - let server = try HTTPServer(port: NWEndpoint.Port(integerLiteral: 8012), tcpOptions: nil, queue: .main, handler: { request, response in - if request.url == "/master.m3u8" { - let _ = (call.externalMediaStream.get() - |> take(1) - |> mapToSignal { externalMediaStream in - return externalMediaStream.masterPlaylistData() - } - |> take(1) - |> deliverOnMainQueue).start(next: { masterPlaylistData in - response.send(masterPlaylistData.data(using: .utf8)!) - }) - } else if request.url == "/hls_level_0.m3u8" { - let _ = (call.externalMediaStream.get() - |> take(1) - |> mapToSignal { externalMediaStream in - return externalMediaStream.playlistData(quality: 0) - } - |> take(1) - |> deliverOnMainQueue).start(next: { playlistData in - response.send(playlistData.data(using: .utf8)!) - }) - } else if request.url == "/hls_level_1.m3u8" { - let _ = (call.externalMediaStream.get() - |> take(1) - |> mapToSignal { externalMediaStream in - return externalMediaStream.playlistData(quality: 1) - } - |> take(1) - |> deliverOnMainQueue).start(next: { playlistData in - response.send(playlistData.data(using: .utf8)!) - }) - } else if request.url.hasPrefix("/hls_stream0_") && request.url.hasSuffix(".ts") { - if let partIndex = Int(request.url[request.url.index(request.url.startIndex, offsetBy: "/hls_stream0_".count).. take(1) - |> mapToSignal { externalMediaStream in - return externalMediaStream.partData(index: partIndex, quality: 0) - } - |> take(1) - |> deliverOnMainQueue).start(next: { partData in - guard let partData else { - return - } - - let sourceTempFile = TempBox.shared.tempFile(fileName: "part.mp4") - let tempFile = TempBox.shared.tempFile(fileName: "part.ts") - defer { - TempBox.shared.dispose(sourceTempFile) - TempBox.shared.dispose(tempFile) - } - - let _ = try? partData.write(to: URL(fileURLWithPath: sourceTempFile.path)) - - let sourcePath = sourceTempFile.path - FFMpegLiveMuxer.remux(sourcePath, to: tempFile.path, offsetSeconds: Double(partIndex)) - if let data = try? Data(contentsOf: URL(fileURLWithPath: tempFile.path)) { - response.send(data) - } else { - let _ = try? response.send("Error") - } - }) - } else { - try response.send("Error") - } - } else if request.url.hasPrefix("/hls_stream1_") && request.url.hasSuffix(".ts") { - if let partIndex = Int(request.url[request.url.index(request.url.startIndex, offsetBy: "/hls_stream1_".count).. take(1) - |> mapToSignal { externalMediaStream in - return externalMediaStream.partData(index: partIndex, quality: 1) - } - |> take(1) - |> deliverOnMainQueue).start(next: { partData in - guard let partData else { - return - } - - let sourceTempFile = TempBox.shared.tempFile(fileName: "part.mp4") - let tempFile = TempBox.shared.tempFile(fileName: "part.ts") - defer { - TempBox.shared.dispose(sourceTempFile) - TempBox.shared.dispose(tempFile) - } - - let _ = try? partData.write(to: URL(fileURLWithPath: sourceTempFile.path)) - - let sourcePath = sourceTempFile.path - FFMpegLiveMuxer.remux(sourcePath, to: tempFile.path, offsetSeconds: Double(partIndex)) - if let data = try? Data(contentsOf: URL(fileURLWithPath: tempFile.path)) { - response.send(data) - } else { - let _ = try? response.send("Error") - } - }) - } else { - try response.send("Error") - } - } else { - try response.send("Error") - } - }) - self.server = server - server.resume() - } catch let e { - print("HTTPServer start error: \(e)") - } - }*/ - let assetUrl = "http://127.0.0.1:\(SharedHLSServer.shared.port)/\(call.internalId)/master.m3u8" Logger.shared.log("MediaStreamVideoComponent", "Initializing HLS asset at \(assetUrl)") #if DEBUG @@ -924,6 +814,7 @@ private final class ProxyVideoView: UIView { let asset = AVURLAsset(url: URL(string: assetUrl)!, options: [:]) self.playerItem = AVPlayerItem(asset: asset) self.player = AVPlayer(playerItem: self.playerItem) + self.player.allowsExternalPlayback = true self.playerLayer = AVPlayerLayer(player: self.player) super.init(frame: CGRect()) diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift index f92963893d..eba9090dd9 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerNavigateToMessage.swift @@ -202,9 +202,9 @@ extension ChatControllerImpl { } var historyView: Signal - let subject: ChatControllerSubject = .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil) + let subject: ChatControllerSubject = .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil, setupReply: false) - historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: nil), count: 50, highlight: true), id: 0), context: self.context, chatLocation: preloadChatLocation, subject: subject, chatLocationContextHolder: Atomic(value: nil), fixedCombinedReadStates: nil, tag: nil, additionalData: []) + historyView = preloadedChatHistoryViewForLocation(ChatHistoryLocationInput(content: .InitialSearch(subject: MessageHistoryInitialSearchSubject(location: searchLocation, quote: nil), count: 50, highlight: true, setupReply: false), id: 0), context: self.context, chatLocation: preloadChatLocation, subject: subject, chatLocationContextHolder: Atomic(value: nil), fixedCombinedReadStates: nil, tag: nil, additionalData: []) var signal: Signal<(MessageIndex?, Bool), NoError> signal = historyView diff --git a/submodules/TelegramVoip/Sources/WrappedMediaStreamingContext.swift b/submodules/TelegramVoip/Sources/WrappedMediaStreamingContext.swift index 0b8e717fa6..d067b85bab 100644 --- a/submodules/TelegramVoip/Sources/WrappedMediaStreamingContext.swift +++ b/submodules/TelegramVoip/Sources/WrappedMediaStreamingContext.swift @@ -235,7 +235,7 @@ public final class ExternalMediaStreamingContext { playlistData.append("hls_stream\(quality)_\(index).ts\n") } - print("Player: updating playlist \(quality) \(minIndex) ... \(headIndex)") + //print("Player: updating playlist \(quality) \(minIndex) ... \(headIndex)") if quality == 0 { self.playlistData.set(.single(playlistData)) @@ -393,6 +393,8 @@ public final class SharedHLSServer { case let .failed(error): Logger.shared.log("SharedHLSServer", "Server failed with error: \(error)") self.listener?.cancel() + + self.listener?.start(queue: self.queue.queue) default: break }