为了账号安全,请及时绑定邮箱和手机立即绑定

Java直播项目学习:从入门到实践指南

标签:
Java 直播

本文详细介绍了Java直播项目的学习和开发过程,涵盖了直播技术概述、Java在直播项目中的应用、开发基本需求及环境搭建等内容。此外,文章还深入解析了Java直播项目的各个核心模块,并提供了实战演练和常见问题的解决方案。通过本文,读者可以全面了解并掌握Java直播项目学习的关键点。Java直播项目学习涉及的技术和实践非常丰富,本文将带领你一步步深入了解。

Java直播项目简介

直播技术概述

直播技术是指通过互联网实时传输视频和音频流的技术。这种技术使用户能够在多个设备上观看实时内容,而无需等待视频文件的下载或上传。它广泛应用于在线教育、娱乐直播、企业培训等多个领域。传统的直播技术通常包括内容采集、编码、传输、解码、播放等几个主要环节,而现代技术则更注重低延迟、高清晰度、互动性以及大规模并发支持。

Java在直播项目中的应用

Java是一种广泛使用的编程语言,因其强大的跨平台特性和丰富的生态系统而被广泛应用于各种应用场景中。在直播项目中,Java可以用于实现流媒体服务器、客户端应用、后台管理等功能。Java提供了丰富的网络编程接口和并发处理机制,使得它非常适合用于开发大规模、高并发的直播系统。此外,Java的开发工具也很成熟,可以方便地进行项目管理和代码调试。

开发直播项目的基本需求

开发一个Java直播项目需要满足以下几个基本需求:

  1. 流媒体传输:需要能够实时传输视频和音频流,要求低延迟和高稳定性。
  2. 用户身份验证:确保只有经过验证的用户才能观看直播,防止未授权访问。
  3. 实时互动:允许观众在直播过程中进行评论、点赞等互动。
  4. 数据统计:实时统计观众数量、在线时长等数据,为运营决策提供支持。
  5. 多平台兼容性:支持在多个平台上观看直播,如PC、手机、平板等。
  6. 扩展性和可维护性:系统需要具有良好的扩展性和易维护性,便于后续迭代和优化。

Java直播项目开发环境搭建

Java开发环境搭建

要开始开发Java直播项目,首先需要搭建Java开发环境。以下是搭建步骤:

  1. 安装JDK

    • 访问Oracle官方网站获取最新的JDK(Java Development Kit)安装包。
    • 根据系统类型(Windows、Linux、macOS)选择对应的安装文件。
    • 安装过程中,确保设置环境变量,如JAVA_HOMEPATH
    • 安装完成后,可以通过命令行输入java -version来确认安装成功。
  2. 安装IDE
    • 推荐使用Eclipse或IntelliJ IDEA作为开发工具。这些工具提供了一系列强大的功能,如代码提示、调试、版本控制集成等。
    • 安装完成后,通过IDE创建新的Java项目,并配置项目依赖。
    • 在IDE中设置项目编码格式,推荐使用UTF-8。

开发工具选择

对于Java开发而言,选择合适的IDE是至关重要的。以下是常见的几种IDE选项:

  • Eclipse

    • Eclipse是一个开源IDE,提供了丰富的插件支持,支持各种编程语言。
    • 常用于Java Web开发,支持Maven和Gradle等项目构建工具。
    • 支持多种版本控制工具,如Git、SVN等。
  • IntelliJ IDEA

    • IntelliJ IDEA提供了强大的代码编辑和调试功能,支持多种语言。
    • 其智能代码补全和语法高亮功能能极大提高开发效率。
    • 可以方便地集成各种版本控制系统,如Git、Mercurial等。
  • NetBeans
    • NetBeans是另一个开源IDE,支持多种编程语言和框架。
    • 支持Java EE开发,可以方便地集成Web开发工具。
    • 提供丰富的插件,如JavaFX、HTML5等。

项目搭建与配置

在开发环境中搭建Java项目,需注意以下步骤:

  1. 创建项目

    • 在IDE中创建一个新的Java项目,为项目命名并选择合适的项目模板。
    • 在项目配置中设置Java版本,推荐使用最新的稳定版本。
  2. 配置依赖

    • 通过项目构建工具(如Maven或Gradle)管理项目依赖。
    • pom.xml(Maven)或build.gradle(Gradle)文件中添加所需库的依赖信息。
    • 示例:使用Maven配置依赖
      <dependencies>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-core</artifactId>
              <version>5.3.10</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
              <version>5.3.10</version>
          </dependency>
          <!-- 其他依赖 -->
      </dependencies>
  3. 配置开发环境
    • 设置项目的编译选项,例如编码格式、源代码兼容性等。
    • 配置版本控制系统,如Git或Mercurial,以便更好地管理和协作开发。
    • 配置测试框架,如JUnit,用于编写和运行单元测试。

Java直播项目核心模块解析

流媒体传输技术介绍

流媒体传输是直播项目中的关键技术之一。它涉及视频和音频的实时传输,通常通过TCP或UDP协议实现。RTMP(Real-Time Messaging Protocol)是目前最常见的流媒体协议之一,它专为实时视频和音频传输设计。RTMP通过TCP连接进行传输,具有较高的可靠性和稳定性,被广泛应用于各种直播平台。

Java直播项目中常用的开源库

在Java直播项目中,开发者可以利用多种开源库来简化开发过程。以下是几个常用的开源库:

  • Xuggler

    • Xuggler是一个用于处理音视频流的Java库,支持RTSP、RTMP等多种协议。
    • 提供了一系列API来处理视频解码、编码、合并等功能。
    • 示例代码:

      import com.xuggle.mediatool.MediaToolChain;
      import com.xuggle.mediatool.MediaWriter;
      import com.xuggle.mediatool.ToolFactory;
      import com.xuggle.mediatool.encode.VideoFileWriter;
      
      public class XugglerExample {
        public static void main(String[] args) throws Exception {
            // 创建MediaToolChain对象
            MediaToolChain toolChain = ToolFactory.makeToolChain();
      
            // 创建MediaWriter对象,指定输出文件格式
            MediaWriter writer = ToolFactory.makeWriter("output.mp4", toolChain);
      
            // 添加视频编码器
            writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, 320, 240);
      
            // 将MediaWriter添加到MediaToolChain中
            toolChain.addMediaTool(writer);
      
            // 开始写入视频流
            writer.open(new File("output.mp4"), toolChain);
      
            // 关闭写入操作
            writer.close();
        }
      }
  • Flume

    • Apache Flume是一个分布式、可靠且高可用的服务,用于收集、聚合和移动大量日志数据。
    • 可以用于实时日志采集、监控等场景。
    • 示例代码:

      import org.apache.flume.Context;
      import org.apache.flume.Event;
      import org.apache.flume.EventDeliveryException;
      import org.apache.flume.PollingFileChannel;
      import org.apache.flume.api.EventV3;
      
      public class FlumeExample {
        public static void main(String[] args) throws Exception {
            // 创建Flume agent
            PollingFileChannel channel = new PollingFileChannel("agent", new Context());
      
            // 创建Event对象
            Event event = EventV3.builder()
                    .setBody("Hello, Flume!".getBytes("UTF-8"))
                    .build();
      
            // 发送Event到channel
            channel.write(event);
        }
      }
  • VLCJ

    • VLCJ是Java的VLC多媒体库绑定,可以用于播放和处理各种音视频格式。
    • 支持多种输入输出方式,如文件、网络流等。
    • 示例代码:

      import uk.co.caprica.vlcj.player.component.AudioMediaPlayerComponent;
      import uk.co.caprica.vlcj.player.component.MediaPlayerComponent;
      
      public class VLCJExample {
        public static void main(String[] args) {
            // 创建MediaPlayerComponent对象
            MediaPlayerComponent mediaPlayer = new AudioMediaPlayerComponent();
      
            // 设置播放媒体文件
            mediaPlayer.mediaPlayer().playMedia("http://example.com/live.m3u8");
      
            // 开始播放
            mediaPlayer.mediaPlayer().play();
        }
      }

各模块功能详解

Java直播项目可以分为多个模块,每个模块负责不同的功能。以下是常见的模块及其功能:

  1. 流媒体服务器

    • 负责接收来自客户端的流媒体请求,并向客户端发送流媒体数据。
    • 实现低延迟、高并发的流媒体传输,支持RTMP、HLS、WebRTC等多种协议。
    • 示例代码(使用VLCJ实现简单的流媒体服务器):

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.event.MediaPlayerEventAdapter;
      
      public class SimpleStreamServer {
          public static void main(String[] args) {
              // 创建MediaPlayerFactory对象
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://example.com/live.m3u8");
      
              // 设置流媒体输出
              mediaPlayer.media().setSout("#standard{access=http,dst=127.0.0.1:8000}");
      
              // 监听播放事件
              mediaPlayer.mediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
                  @Override
                  public void finished(MediaPlayer mediaPlayer) {
                      System.out.println("Playback finished.");
                  }
              });
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }
  2. 客户端应用

    • 负责接收流媒体服务器发送的数据,并在设备上显示视频和音频流。
    • 支持多种设备,如PC、手机、平板等。
    • 示例代码(使用VLCJ实现简单的客户端应用):

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.event.MediaPlayerEventAdapter;
      
      public class SimpleStreamClient {
          public static void main(String[] args) {
              // 创建MediaPlayerFactory对象
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://127.0.0.1:8000/live.m3u8");
      
              // 监听播放事件
              mediaPlayer.mediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
                  @Override
                  public void finished(MediaPlayer mediaPlayer) {
                      System.out.println("Playback finished.");
                  }
              });
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }
  3. 后台管理系统

    • 负责管理直播项目的核心功能,如用户管理、权限控制、直播管理等。
    • 提供后台管理系统,方便管理员进行操作。
    • 示例代码(使用Spring Boot实现简单的后台管理服务):

      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      
      @SpringBootApplication
      public class SimpleAdminService {
          public static void main(String[] args) {
              SpringApplication.run(SimpleAdminService.class, args);
          }
      }
  4. 实时互动模块

    • 提供实时互动功能,如评论、点赞、礼物等。
    • 实现低延迟的互动体验,确保用户操作的实时响应。
    • 示例代码(使用Spring Boot实现简单的实时互动服务):

      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class SimpleInteractionService {
          @GetMapping("/comment")
          public String getComment() {
              return "Hello, this is a comment.";
          }
      }

实战演练:搭建一个简单的Java直播项目

项目需求分析

在搭建一个简单的Java直播项目之前,我们需要明确项目需求:

  • 技术选型:选择合适的流媒体协议(如RTMP、HLS、WebRTC等)和开发工具(如Eclipse、IntelliJ IDEA等)。
  • 功能需求:实现视频直播、用户身份验证、实时互动等功能。
  • 性能要求:确保系统具有高并发处理能力和低延迟。
  • 兼容性:支持多种平台和设备,如PC、手机、平板等。

项目设计与实现

在明确需求后,我们可以开始设计和实现Java直播项目。以下是设计和实现的步骤:

  1. 项目结构设计

    • 将项目分为几个模块,如流媒体服务器、客户端应用、后台管理系统等。
    • 每个模块负责不同的功能,实现模块化设计。
  2. 编码实现

    • 使用Java和相关库实现各个模块的功能。
    • 代码示例:

      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class StreamingService {
          @GetMapping("/stream")
          public String getStreamUrl() {
              return "http://example.com/live.m3u8";
          }
      }
  3. 测试与调试
    • 编写单元测试和集成测试,确保每个模块的功能正确。
    • 使用调试工具进行调试,排除代码中的潜在错误。

代码示例与解析

以下是部分关键代码示例及解析:

  1. 流媒体服务器示例

    • 使用VLCJ实现简单的流媒体服务器。
    • 示例代码:

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.event.MediaPlayerEventAdapter;
      
      public class SimpleStreamServer {
          public static void main(String[] args) {
              // 创建MediaPlayerFactory对象
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://example.com/live.m3u8");
      
              // 设置流媒体输出
              mediaPlayer.media().setSout("#standard{access=http,dst=127.0.0.1:8000}");
      
              // 监听播放事件
              mediaPlayer.mediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
                  @Override
                  public void finished(MediaPlayer mediaPlayer) {
                      System.out.println("Playback finished.");
                  }
              });
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }
    • 解析:这段代码创建了一个简单的流媒体服务器,使用VLCJ库实现了RTMP流媒体服务。通过MediaPlayer对象播放指定的媒体文件,并将输出流设置为HTTP协议,监听端口为8000。
  2. 客户端应用示例

    • 使用VLCJ实现简单的客户端应用。
    • 示例代码:

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.event.MediaPlayerEventAdapter;
      
      public class SimpleStreamClient {
          public static void main(String[] args) {
              // 创建MediaPlayerFactory对象
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://127.0.0.1:8000/live.m3u8");
      
              // 监听播放事件
              mediaPlayer.mediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
                  @Override
                  public void finished(MediaPlayer mediaPlayer) {
                      System.out.println("Playback finished.");
                  }
              });
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }
    • 解析:这段代码实现了简单的客户端应用,使用VLCJ库播放来自流媒体服务器的RTMP流。客户端应用通过HTTP协议从服务器获取流媒体数据并播放。

Java直播项目常见问题与解决方案

项目开发常见问题

在开发Java直播项目时,经常会遇到一些常见的问题,以下是一些常见问题及其解决方案:

  1. 流媒体传输延迟高

    • 问题描述:流媒体传输延迟高,导致观看体验不佳。
    • 解决方案:优化网络传输设置,选择合适的流媒体协议,如RTMP、HLS等。
    • 示例

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      
      public class SimpleStreamServer {
          public static void main(String[] args) {
              // 创建MediaPlayerFactory对象
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://example.com/live.m3u8");
      
              // 设置流媒体输出
              mediaPlayer.media().setSout("#standard{access=rtmp,dst=127.0.0.1:1935/live}");
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }
  2. 并发处理能力不足

    • 问题描述:系统无法处理大量并发请求,导致性能下降。
    • 解决方案:优化系统架构,使用负载均衡和集群技术提高并发处理能力。
    • 示例

      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class StreamingService {
          @GetMapping("/stream")
          public String getStreamUrl() {
              // 负载均衡配置
              return "http://loadbalancer/live.m3u8";
          }
      }

测试与调试技巧

在开发过程中,测试和调试是非常重要的环节。以下是几个常用的测试与调试技巧:

  1. 单元测试

    • 使用JUnit等测试框架编写单元测试,确保每个模块的功能正确。
    • 示例代码:

      import org.junit.jupiter.api.Test;
      import static org.junit.jupiter.api.Assertions.assertEquals;
      
      public class StreamingServiceTest {
          @Test
          public void testGetStreamUrl() {
              StreamingService service = new StreamingService();
              String url = service.getStreamUrl();
              assertEquals("http://example.com/live.m3u8", url);
          }
      }
  2. 集成测试

    • 编写集成测试,测试系统中各模块之间的交互。
    • 示例代码:

      import org.junit.jupiter.api.Test;
      import static org.junit.jupiter.api.Assertions.assertTrue;
      
      public class IntegrationTest {
          @Test
          public void testStreamServer() {
              // 启动流媒体服务器
              SimpleStreamServer server = new SimpleStreamServer();
              server.main(new String[] {});
      
              // 测试客户端能否正确连接并播放流媒体
              SimpleStreamClient client = new SimpleStreamClient();
              client.main(new String[] {});
      
              assertTrue(true);
          }
      }
  3. 调试技巧
    • 使用IDE中的调试功能,逐步执行代码,查看变量值。
    • 打印调试信息,使用System.out.println或日志框架输出关键信息。
    • 示例代码:
      public class SimpleStreamServer {
          public static void main(String[] args) {
              System.out.println("Starting stream server...");
              // 启动流媒体服务器
              // ...
              System.out.println("Stream server started.");
          }
      }

性能优化策略

性能优化是确保直播项目稳定运行的关键。以下是几种常见的性能优化策略:

  1. 代码优化

    • 优化代码逻辑,减少不必要的计算和操作。
    • 示例代码:
      public class OptimizedService {
          public String getStreamUrl() {
              // 优化逻辑
              return "http://example.com/live.m3u8";
          }
      }
  2. 资源优化

    • 合理分配服务器资源,如CPU、内存等。
    • 使用缓存技术减少数据库访问次数。
    • 示例代码:

      import org.springframework.cache.annotation.Cacheable;
      import org.springframework.stereotype.Service;
      
      @Service
      public class StreamingService {
          @Cacheable("streamUrls")
          public String getStreamUrl() {
              // 查询数据库获取流媒体URL
              return "http://example.com/live.m3u8";
          }
      }
  3. 网络优化

    • 优化网络传输协议,选择更适合的流媒体协议。
    • 使用CDN加速流媒体传输。
    • 示例代码:

      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayer;
      import uk.co.caprica.vlcj.player.direct.mediaplayer.MediaPlayerFactory;
      
      public class SimpleStreamServer {
          public static void main(String[] args) {
              // 使用CDN加速流媒体传输
              MediaPlayerFactory factory = new MediaPlayerFactory();
              MediaPlayer mediaPlayer = factory.mediaPlayer();
      
              // 设置播放媒体文件
              mediaPlayer.media().playMedia("http://cdn.example.com/live.m3u8");
      
              // 开始播放
              mediaPlayer.mediaPlayer().play();
          }
      }

Java直播项目的部署与维护

项目发布与部署

将开发好的Java直播项目发布并部署到生产环境,是将项目交付给用户的最后一步。以下是部署步骤:

  1. 构建项目

    • 使用Maven或Gradle构建项目,生成可部署的WAR文件。
    • 示例代码:
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-war-plugin</artifactId>
                  <version>3.3.1</version>
              </plugin>
          </plugins>
      </build>
  2. 部署到服务器

    • 将构建好的WAR文件部署到应用服务器,如Tomcat、Jetty等。
    • 配置服务器环境,如设置JVM参数、部署目录等。
    • 示例代码:
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.1</version>
          <configuration>
              <source>1.8</source>
              <target>1.8</target>
          </configuration>
      </plugin>
  3. 启动应用服务器
    • 启动应用服务器,确保项目能够正常运行。
    • 配置监控和日志记录,以便及时发现和解决问题。
    • 示例代码:
      # 启动Tomcat
      sh /path/to/tomcat/bin/startup.sh

项目运维与监控

在项目上线后,运维和监控是保持系统稳定运行的重要环节。以下是几个关键步骤:

  1. 系统监控

    • 使用监控工具(如Prometheus、Grafana)监控系统CPU、内存、网络等资源使用情况。
    • 示例代码:
      scrape_configs:
        - job_name: 'stream-server'
          static_configs:
            - targets: ['localhost:9090']
  2. 日志管理

    • 配置日志记录,记录系统运行日志和错误日志。
    • 使用日志分析工具(如ELK Stack)进行日志分析和故障排查。
    • 示例代码:

      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      public class StreamingService {
          private static final Logger logger = LoggerFactory.getLogger(StreamingService.class);
      
          public String getStreamUrl() {
              logger.info("Getting stream URL...");
              return "http://example.com/live.m3u8";
          }
      }
  3. 故障处理
    • 及时响应系统故障,确保服务可用性。
    • 使用备份和恢复策略,防止数据丢失。
    • 示例代码:
      # 创建备份脚本
      cp /path/to/app /path/to/backup/app

常见故障处理与维护

在运行Java直播项目时,可能会遇到一些常见故障,以下是一些常见的故障处理方法:

  1. 网络连接问题

    • 故障描述:服务器与客户端之间网络连接不稳定,导致直播卡顿或无法播放。
    • 解决方案:检查网络配置,优化网络连接;使用CDN加速流媒体传输。
    • 示例代码
      public class NetworkCheckService {
          public boolean isNetworkAvailable() {
              // 检查网络连接
              return true;
          }
      }
  2. 内存泄露问题

    • 故障描述:系统运行一段时间后,内存占用逐渐增加,导致系统变慢甚至崩溃。
    • 解决方案:定期检查代码逻辑,优化内存管理;使用内存分析工具(如JProfiler)进行分析。
    • 示例代码
      public class MemoryCheckService {
          public boolean isMemoryLeak() {
              // 检查内存泄漏
              return false;
          }
      }
  3. 并发处理问题
    • 故障描述:系统无法处理大量并发请求,导致性能下降。
    • 解决方案:优化系统架构,使用负载均衡和集群技术提高并发处理能力。
    • 示例代码
      public class ConcurrencyCheckService {
          public boolean isConcurrencyIssue() {
              // 检查并发处理问题
              return false;
          }
      }
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消